From e0a0b2493a2585db1a1037206c321b05b1fdbb84 Mon Sep 17 00:00:00 2001 From: Xykota Date: Mon, 6 Nov 2023 14:08:07 +0700 Subject: [PATCH] deploy(hardhat): v1.27.0 --- .../hardhat/deployments/arbitrum/Curve.json | 131 +++++++-- .../deployments/arbitrum/Stargate.json | 98 ++++++- .../deployments/arbitrum/UniV2LikeFacet.json | 179 +++++++++++-- .../deployments/arbitrum/UniV3Callback.json | 26 +- .../deployments/arbitrum/UniV3Like.json | 171 ++++++++++-- .../deployments/arbitrum/WarpLink.json | 95 +++++-- .../c6735d71c8937120ee5b82bc32fb5df3.json | 170 ++++++++++++ .../hardhat/deployments/avalanche/Curve.json | 131 +++++++-- .../deployments/avalanche/Stargate.json | 100 +++++-- .../deployments/avalanche/UniV2LikeFacet.json | 181 +++++++++++-- .../deployments/avalanche/UniV3Callback.json | 26 +- .../deployments/avalanche/UniV3Like.json | 171 ++++++++++-- .../deployments/avalanche/WarpLink.json | 95 +++++-- .../c6735d71c8937120ee5b82bc32fb5df3.json | 170 ++++++++++++ packages/hardhat/deployments/base/Curve.json | 129 ++++++++- .../hardhat/deployments/base/Stargate.json | 100 +++++-- .../deployments/base/UniV2LikeFacet.json | 181 +++++++++++-- .../deployments/base/UniV3Callback.json | 28 +- .../hardhat/deployments/base/UniV3Like.json | 171 ++++++++++-- .../hardhat/deployments/base/WarpLink.json | 95 +++++-- .../c6735d71c8937120ee5b82bc32fb5df3.json | 170 ++++++++++++ packages/hardhat/deployments/bsc/Curve.json | 131 +++++++-- .../hardhat/deployments/bsc/Stargate.json | 100 +++++-- .../deployments/bsc/UniV2LikeFacet.json | 181 +++++++++++-- .../deployments/bsc/UniV3Callback.json | 28 +- .../hardhat/deployments/bsc/UniV3Like.json | 171 ++++++++++-- .../hardhat/deployments/bsc/WarpLink.json | 95 +++++-- .../c6735d71c8937120ee5b82bc32fb5df3.json | 170 ++++++++++++ .../hardhat/deployments/mainnet/Curve.json | 131 +++++++-- .../hardhat/deployments/mainnet/Stargate.json | 100 +++++-- .../deployments/mainnet/UniV2LikeFacet.json | 181 +++++++++++-- .../deployments/mainnet/UniV2RouterFacet.json | 161 +++++++++-- .../deployments/mainnet/UniV3Callback.json | 28 +- .../deployments/mainnet/UniV3Like.json | 171 ++++++++++-- .../hardhat/deployments/mainnet/WarpLink.json | 95 +++++-- .../b02a0ce4f8d2d52325669cdc01d21082.json | 251 ++++++++++++++++++ .../c6735d71c8937120ee5b82bc32fb5df3.json | 170 ++++++++++++ .../hardhat/deployments/optimism/Curve.json | 131 +++++++-- .../deployments/optimism/Stargate.json | 100 +++++-- .../deployments/optimism/UniV2LikeFacet.json | 181 +++++++++++-- .../deployments/optimism/UniV3Callback.json | 28 +- .../deployments/optimism/UniV3Like.json | 171 ++++++++++-- .../deployments/optimism/WarpLink.json | 95 +++++-- .../c6735d71c8937120ee5b82bc32fb5df3.json | 170 ++++++++++++ packages/hardhat/package.json | 2 +- 45 files changed, 5089 insertions(+), 571 deletions(-) create mode 100644 packages/hardhat/deployments/arbitrum/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json create mode 100644 packages/hardhat/deployments/avalanche/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json create mode 100644 packages/hardhat/deployments/base/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json create mode 100644 packages/hardhat/deployments/bsc/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json create mode 100644 packages/hardhat/deployments/mainnet/solcInputs/b02a0ce4f8d2d52325669cdc01d21082.json create mode 100644 packages/hardhat/deployments/mainnet/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json create mode 100644 packages/hardhat/deployments/optimism/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json diff --git a/packages/hardhat/deployments/arbitrum/Curve.json b/packages/hardhat/deployments/arbitrum/Curve.json index 52b708c3..57186136 100644 --- a/packages/hardhat/deployments/arbitrum/Curve.json +++ b/packages/hardhat/deployments/arbitrum/Curve.json @@ -1,5 +1,5 @@ { - "address": "0x205E9444cC0b0266CdB8Ea064c335B10aaCe50C3", + "address": "0xa05F221d029754a011D62f6a3bf7bf27430D46d6", "abi": [ { "inputs": [], @@ -38,6 +38,11 @@ "name": "InsufficientOutputAmount", "type": "error" }, + { + "inputs": [], + "name": "PermitForEthToken", + "type": "error" + }, { "inputs": [], "name": "UnhandledPoolKind", @@ -116,6 +121,97 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "curveExactInputSingle", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -213,7 +309,7 @@ "type": "tuple" } ], - "name": "curveExactInputSingle", + "name": "curveExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -225,28 +321,28 @@ "type": "function" } ], - "transactionHash": "0xd0dfb27ad88ff92dd1d2bd93bdf79677b1a2e4233f011701259c999ccc9ab526", + "transactionHash": "0xed0c69d17ee6eb46a0788a15f79c05819dc69fb5350bd7af36ebf46e835b45f2", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x205E9444cC0b0266CdB8Ea064c335B10aaCe50C3", - "transactionIndex": 1, - "gasUsed": "7058661", + "contractAddress": "0xa05F221d029754a011D62f6a3bf7bf27430D46d6", + "transactionIndex": 3, + "gasUsed": "13010928", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xa0c77dc6c4095e6c41b0f8987dc64061b2365dc714d0a670ce2b0ca2ebb879f4", - "transactionHash": "0xd0dfb27ad88ff92dd1d2bd93bdf79677b1a2e4233f011701259c999ccc9ab526", + "blockHash": "0x233c24a2f4a374c15c868d4d59c2a7c32df728ea364447f108eb4d492aa2e7bf", + "transactionHash": "0xed0c69d17ee6eb46a0788a15f79c05819dc69fb5350bd7af36ebf46e835b45f2", "logs": [], - "blockNumber": 144392599, - "cumulativeGasUsed": "7058661", + "blockNumber": 147606608, + "cumulativeGasUsed": "14746577", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 11, - "solcInputHash": "ebf955869df0dfecc3a0eb12547e8afc", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 useEth: params.tokenIn == address(0) || isToEth,\\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0x6d796fc46a41bd9fe76ae989d273f90aa0298f993f5c77cf481f5968fad21474\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\\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\":\"0x88d6dcf171951cf8e3f3488ef5d66a953614ae48926f9ace36d58b095bf9dc84\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506117d5806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b6100366100313660046113ad565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906114ed565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff9091169161066b565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b90890189611506565b6040518563ffffffff1660e01b815260040161026a9493929190611572565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b6103cc856101800151866101a001518760600151348961014001518a61016001518b6000015160008073ffffffffffffffffffffffffffffffffffffffff168e60e0015173ffffffffffffffffffffffffffffffffffffffff1614806103c757508a5b6107df565b60008261046d576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046891906114ed565b61046f565b475b905061047b8282611663565b935061048f86602001518760a00151610cdb565b8410156104c8576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ea8660c00151876101000151886080015161ffff16896020015188610d0b565b93508215610596576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610550576040519150601f19603f3d011682016040523d82523d6000602084013e610555565b606091505b5050905080610590576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506105ca565b6105ca86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610dc49092919063ffffffff16565b85610100015173ffffffffffffffffffffffffffffffffffffffff168660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f389600001518860405161065a929190918252602082015260400190565b60405180910390a450505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106f78482610e1f565b6107d95760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526107cf9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610ee0565b6107d98482610ee0565b50505050565b8860ff1660010361090d578715610898576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b5050505050610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610861565b8860ff16600203610a4d5787156109d8576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156109ad573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109d291906114ed565b50610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df0212490889060840161098f565b8860ff16600303610bee578715610acb576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b90889060840161098f565b8015610b45576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a40161098f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015610bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d291906114ed565b8860ff16600403610c9e578715610c31576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610861565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6000612710610cea8382611676565b610cf89061ffff1685611698565b610d0291906116af565b90505b92915050565b60006107d0841115610d52576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610d64575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610d9a5760646032840204610d9d565b60005b9050808303838214610db557610db58a8a8484610fef565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e1a9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161074d565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e49919061170e565b6000604051808303816000865af19150503d8060008114610e86576040519150601f19603f3d011682016040523d82523d6000602084013e610e8b565b606091505b5091509150818015610eb5575080511580610eb5575080806020019051810190610eb5919061172a565b8015610ed7575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166110b79092919063ffffffff16565b9050805160001480610f63575080806020019051810190610f63919061172a565b610e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d49565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60606110c684846000856110ce565b949350505050565b606082471015611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d49565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611189919061170e565b60006040518083038185875af1925050503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b50915091506111dc878383876111e7565b979650505050505050565b6060831561127d5782516000036112765773ffffffffffffffffffffffffffffffffffffffff85163b611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d49565b50816110c6565b6110c683838151156112925781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d49919061174e565b6040516101c0810167ffffffffffffffff81118282101715611311577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133b57600080fd5b919050565b803561ffff8116811461133b57600080fd5b803565ffffffffffff8116811461133b57600080fd5b803560ff8116811461133b57600080fd5b801515811461138757600080fd5b50565b803561133b81611379565b6000604082840312156113a757600080fd5b50919050565b6000808284036101e08112156113c257600080fd5b6101c0808212156113d257600080fd5b6113da6112c6565b915084358252602085013560208301526113f660408601611317565b604083015261140760608601611317565b606083015261141860808601611340565b608083015261142960a08601611340565b60a083015261143a60c08601611317565b60c083015261144b60e08601611317565b60e083015261010061145e818701611317565b90830152610120611470868201611352565b90830152610140611482868201611368565b90830152610160611494868201611368565b908301526101806114a6868201611368565b908301526101a06114b886820161138a565b9083015290925083013567ffffffffffffffff8111156114d757600080fd5b6114e385828601611395565b9150509250929050565b6000602082840312156114ff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261153b57600080fd5b83018035915067ffffffffffffffff82111561155657600080fd5b60200191503681900382131561156b57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d0557610d05611634565b61ffff82811682821603908082111561169157611691611634565b5092915050565b8082028115828204841417610d0557610d05611634565b6000826116e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156117055781810151838201526020016116ed565b50506000910152565b600082516117208184602087016116ea565b9190910192915050565b60006020828403121561173c57600080fd5b815161174781611379565b9392505050565b602081526000825180602084015261176d8160408501602087016116ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212204f164ad9f74d85efb515fab3ce059723b15ff2d1b51c1308c6989e26aff5f0c564736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b6100366100313660046113ad565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906114ed565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff9091169161066b565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b90890189611506565b6040518563ffffffff1660e01b815260040161026a9493929190611572565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b6103cc856101800151866101a001518760600151348961014001518a61016001518b6000015160008073ffffffffffffffffffffffffffffffffffffffff168e60e0015173ffffffffffffffffffffffffffffffffffffffff1614806103c757508a5b6107df565b60008261046d576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046891906114ed565b61046f565b475b905061047b8282611663565b935061048f86602001518760a00151610cdb565b8410156104c8576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ea8660c00151876101000151886080015161ffff16896020015188610d0b565b93508215610596576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610550576040519150601f19603f3d011682016040523d82523d6000602084013e610555565b606091505b5050905080610590576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506105ca565b6105ca86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610dc49092919063ffffffff16565b85610100015173ffffffffffffffffffffffffffffffffffffffff168660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f389600001518860405161065a929190918252602082015260400190565b60405180910390a450505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106f78482610e1f565b6107d95760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526107cf9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610ee0565b6107d98482610ee0565b50505050565b8860ff1660010361090d578715610898576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b5050505050610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610861565b8860ff16600203610a4d5787156109d8576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156109ad573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109d291906114ed565b50610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df0212490889060840161098f565b8860ff16600303610bee578715610acb576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b90889060840161098f565b8015610b45576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a40161098f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015610bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d291906114ed565b8860ff16600403610c9e578715610c31576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610861565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6000612710610cea8382611676565b610cf89061ffff1685611698565b610d0291906116af565b90505b92915050565b60006107d0841115610d52576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610d64575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610d9a5760646032840204610d9d565b60005b9050808303838214610db557610db58a8a8484610fef565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e1a9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161074d565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e49919061170e565b6000604051808303816000865af19150503d8060008114610e86576040519150601f19603f3d011682016040523d82523d6000602084013e610e8b565b606091505b5091509150818015610eb5575080511580610eb5575080806020019051810190610eb5919061172a565b8015610ed7575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166110b79092919063ffffffff16565b9050805160001480610f63575080806020019051810190610f63919061172a565b610e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d49565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60606110c684846000856110ce565b949350505050565b606082471015611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d49565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611189919061170e565b60006040518083038185875af1925050503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b50915091506111dc878383876111e7565b979650505050505050565b6060831561127d5782516000036112765773ffffffffffffffffffffffffffffffffffffffff85163b611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d49565b50816110c6565b6110c683838151156112925781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d49919061174e565b6040516101c0810167ffffffffffffffff81118282101715611311577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133b57600080fd5b919050565b803561ffff8116811461133b57600080fd5b803565ffffffffffff8116811461133b57600080fd5b803560ff8116811461133b57600080fd5b801515811461138757600080fd5b50565b803561133b81611379565b6000604082840312156113a757600080fd5b50919050565b6000808284036101e08112156113c257600080fd5b6101c0808212156113d257600080fd5b6113da6112c6565b915084358252602085013560208301526113f660408601611317565b604083015261140760608601611317565b606083015261141860808601611340565b608083015261142960a08601611340565b60a083015261143a60c08601611317565b60c083015261144b60e08601611317565b60e083015261010061145e818701611317565b90830152610120611470868201611352565b90830152610140611482868201611368565b90830152610160611494868201611368565b908301526101806114a6868201611368565b908301526101a06114b886820161138a565b9083015290925083013567ffffffffffffffff8111156114d757600080fd5b6114e385828601611395565b9150509250929050565b6000602082840312156114ff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261153b57600080fd5b83018035915067ffffffffffffffff82111561155657600080fd5b60200191503681900382131561156b57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d0557610d05611634565b61ffff82811682821603908082111561169157611691611634565b5092915050565b8082028115828204841417610d0557610d05611634565b6000826116e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156117055781810151838201526020016116ed565b50506000910152565b600082516117208184602087016116ea565b9190910192915050565b60006020828403121561173c57600080fd5b815161174781611379565b9392505050565b602081526000825180602084015261176d8160408501602087016116ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212204f164ad9f74d85efb515fab3ce059723b15ff2d1b51c1308c6989e26aff5f0c564736f6c63430008130033", + "numDeployments": 12, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermitForEthToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"name\":\"curveExactInputSingle\",\"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\":\"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\":\"curveExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}],\"PermitForEthToken()\":[{\"notice\":\"A function expecting a permit was used when the input token is ETH\"}]},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\\n * Perform the swap with tokens already moved to this contract\\n */\\n function curveExactInputSingleInternal(\\n ExactInputSingleParams calldata params\\n ) internal returns (uint256 amountOut) {\\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 LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n useEth: params.tokenIn == address(0) || isToEth,\\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function curveExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (params.tokenIn == address(0)) {\\n revert PermitForEthToken();\\n }\\n\\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 return curveExactInputSingleInternal(params);\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\\n }\\n\\n return curveExactInputSingleInternal(params);\\n }\\n}\\n\",\"keccak256\":\"0x14d74eb8ac6efa00532e5de577c6b6ca66866e6991a220986ca7733d920de561\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n /**\\n * A function expecting a permit was used when the input token is ETH\\n */\\n error PermitForEthToken();\\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 curveExactInputSinglePermit(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xd034586f038b6ea01e6ce9d6497d203ef8cc5d221884f1a6f608ce08bae51904\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506119c8806100206000396000f3fe6080604052600436106100295760003560e01c806356bf88f01461002e578063aef417b114610053575b600080fd5b61004161003c366004611598565b610066565b60405190815260200160405180910390f35b6100416100613660046115f0565b610348565b60008061007a610100850160e0860161160d565b73ffffffffffffffffffffffffffffffffffffffff16036100c7576040517f53e40ce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a6100da608085016060860161160d565b84356100ed610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff169190610430565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925273ffffffffffffffffffffffffffffffffffffffff90921691632b67b57091339190819060608201908190610174906101008c01908c0161160d565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016101ab6101408b016101208c0161164a565b65ffffffffffff908116825289351660209182015290825230908201526040016101dd61014089016101208a0161164a565b65ffffffffffff1690526101f46020870187611672565b6040518563ffffffff1660e01b815260040161021394939291906116de565b600060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505061026c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333086356102a0610100890160e08a0161160d565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561031e57600080fd5b505af1158015610332573d6000803e3d6000fd5b5050505061033f836105a4565b90505b92915050565b600061035c6101408301610120840161164a565b65ffffffffffff1642111561039d576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103b0610100840160e0850161160d565b73ffffffffffffffffffffffffffffffffffffffff1614610427576103f16103de608084016060850161160d565b83356100ed610100860160e0870161160d565b61042733308435610409610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff16929190610a43565b610342826105a4565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526104bc8482610aa1565b61059e5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526105949085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610b62565b61059e8482610b62565b50505050565b600080806105ba6101208501610100860161160d565b73ffffffffffffffffffffffffffffffffffffffff16149050600081610681576105ec6101208501610100860161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c91906117a0565b610683565b475b905061073661069a6101a0860161018087016117b9565b6106ac6101c087016101a088016117ed565b6106bc608088016060890161160d565b346106cf6101608a016101408b016117b9565b6106e16101808b016101608c016117b9565b8a6000013560008073ffffffffffffffffffffffffffffffffffffffff168d60e0016020810190610712919061160d565b73ffffffffffffffffffffffffffffffffffffffff16148061073157508a5b610c7b565b6000826107e45761074f6101208601610100870161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df91906117a0565b6107e6565b475b90506107f28282611839565b9350610811602086013561080c60c0880160a0890161184c565b611177565b84101561084a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088e61085d60e0870160c0880161160d565b61086f6101208801610100890161160d565b61087f60a0890160808a0161184c565b61ffff1688602001358861119e565b935082156109455760006108a8606087016040880161160d565b73ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146108ff576040519150601f19603f3d011682016040523d82523d6000602084013e610904565b606091505b505090508061093f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610988565b610988610958606087016040880161160d565b8561096b61012089016101008a0161160d565b73ffffffffffffffffffffffffffffffffffffffff169190611252565b61099a6101208601610100870161160d565b73ffffffffffffffffffffffffffffffffffffffff166109c1610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff166109e760e0880160c0890161160d565b60408051893581526020810189905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261059e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610512565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610acb9190611894565b6000604051808303816000865af19150503d8060008114610b08576040519150601f19603f3d011682016040523d82523d6000602084013e610b0d565b606091505b5091509150818015610b37575080511580610b37575080806020019051810190610b3791906118b0565b8015610b59575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610bc4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112a89092919063ffffffff16565b9050805160001480610be5575080806020019051810190610be591906118b0565b610c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b8860ff16600103610da9578715610d34576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015610d1657600080fd5b505af1158015610d2a573d6000803e3d6000fd5b505050505061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610cfd565b8860ff16600203610ee9578715610e74576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015610e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b5061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610e2b565b8860ff1660030361108a578715610f67576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401610e2b565b8015610fe1576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401610e2b565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015611066573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b8860ff1660040361113a5787156110cd576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610cfd565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600061271061118683826118cd565b6111949061ffff16856118ef565b61033f9190611906565b60006107d08411156111e0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d06004820152602401610c6d565b600082848111156111f2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611228576064603284020461122b565b60005b9050808303838214611243576112438a8a84846112bf565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c769084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610512565b60606112b78484600085611387565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606082471015611419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c6d565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516114429190611894565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b5091509150611495878383876114a0565b979650505050505050565b6060831561153657825160000361152f5773ffffffffffffffffffffffffffffffffffffffff85163b61152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c6d565b50816112b7565b6112b7838381511561154b5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9190611941565b60006101c0828403121561159257600080fd5b50919050565b6000806101e083850312156115ac57600080fd5b6115b6848461157f565b91506101c083013567ffffffffffffffff8111156115d357600080fd5b8301604081860312156115e557600080fd5b809150509250929050565b60006101c0828403121561160357600080fd5b61033f838361157f565b60006020828403121561161f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461164357600080fd5b9392505050565b60006020828403121561165c57600080fd5b813565ffffffffffff8116811461164357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126116a757600080fd5b83018035915067ffffffffffffffff8211156116c257600080fd5b6020019150368190038213156116d757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156117b257600080fd5b5051919050565b6000602082840312156117cb57600080fd5b813560ff8116811461164357600080fd5b80151581146117ea57600080fd5b50565b6000602082840312156117ff57600080fd5b8135611643816117dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156103425761034261180a565b60006020828403121561185e57600080fd5b813561ffff8116811461164357600080fd5b60005b8381101561188b578181015183820152602001611873565b50506000910152565b600082516118a6818460208701611870565b9190910192915050565b6000602082840312156118c257600080fd5b8151611643816117dc565b61ffff8281168282160390808211156118e8576118e861180a565b5092915050565b80820281158282048414176103425761034261180a565b60008261193c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6020815260008251806020840152611960816040850160208701611870565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202b55d2f11aa7f1395a3e9c79ad5594ecdb6d8158214c767aed2d3da3a5500d1264736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c806356bf88f01461002e578063aef417b114610053575b600080fd5b61004161003c366004611598565b610066565b60405190815260200160405180910390f35b6100416100613660046115f0565b610348565b60008061007a610100850160e0860161160d565b73ffffffffffffffffffffffffffffffffffffffff16036100c7576040517f53e40ce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a6100da608085016060860161160d565b84356100ed610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff169190610430565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925273ffffffffffffffffffffffffffffffffffffffff90921691632b67b57091339190819060608201908190610174906101008c01908c0161160d565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016101ab6101408b016101208c0161164a565b65ffffffffffff908116825289351660209182015290825230908201526040016101dd61014089016101208a0161164a565b65ffffffffffff1690526101f46020870187611672565b6040518563ffffffff1660e01b815260040161021394939291906116de565b600060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505061026c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333086356102a0610100890160e08a0161160d565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561031e57600080fd5b505af1158015610332573d6000803e3d6000fd5b5050505061033f836105a4565b90505b92915050565b600061035c6101408301610120840161164a565b65ffffffffffff1642111561039d576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103b0610100840160e0850161160d565b73ffffffffffffffffffffffffffffffffffffffff1614610427576103f16103de608084016060850161160d565b83356100ed610100860160e0870161160d565b61042733308435610409610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff16929190610a43565b610342826105a4565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526104bc8482610aa1565b61059e5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526105949085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610b62565b61059e8482610b62565b50505050565b600080806105ba6101208501610100860161160d565b73ffffffffffffffffffffffffffffffffffffffff16149050600081610681576105ec6101208501610100860161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c91906117a0565b610683565b475b905061073661069a6101a0860161018087016117b9565b6106ac6101c087016101a088016117ed565b6106bc608088016060890161160d565b346106cf6101608a016101408b016117b9565b6106e16101808b016101608c016117b9565b8a6000013560008073ffffffffffffffffffffffffffffffffffffffff168d60e0016020810190610712919061160d565b73ffffffffffffffffffffffffffffffffffffffff16148061073157508a5b610c7b565b6000826107e45761074f6101208601610100870161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df91906117a0565b6107e6565b475b90506107f28282611839565b9350610811602086013561080c60c0880160a0890161184c565b611177565b84101561084a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088e61085d60e0870160c0880161160d565b61086f6101208801610100890161160d565b61087f60a0890160808a0161184c565b61ffff1688602001358861119e565b935082156109455760006108a8606087016040880161160d565b73ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146108ff576040519150601f19603f3d011682016040523d82523d6000602084013e610904565b606091505b505090508061093f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610988565b610988610958606087016040880161160d565b8561096b61012089016101008a0161160d565b73ffffffffffffffffffffffffffffffffffffffff169190611252565b61099a6101208601610100870161160d565b73ffffffffffffffffffffffffffffffffffffffff166109c1610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff166109e760e0880160c0890161160d565b60408051893581526020810189905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261059e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610512565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610acb9190611894565b6000604051808303816000865af19150503d8060008114610b08576040519150601f19603f3d011682016040523d82523d6000602084013e610b0d565b606091505b5091509150818015610b37575080511580610b37575080806020019051810190610b3791906118b0565b8015610b59575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610bc4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112a89092919063ffffffff16565b9050805160001480610be5575080806020019051810190610be591906118b0565b610c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b8860ff16600103610da9578715610d34576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015610d1657600080fd5b505af1158015610d2a573d6000803e3d6000fd5b505050505061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610cfd565b8860ff16600203610ee9578715610e74576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015610e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b5061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610e2b565b8860ff1660030361108a578715610f67576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401610e2b565b8015610fe1576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401610e2b565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015611066573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b8860ff1660040361113a5787156110cd576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610cfd565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600061271061118683826118cd565b6111949061ffff16856118ef565b61033f9190611906565b60006107d08411156111e0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d06004820152602401610c6d565b600082848111156111f2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611228576064603284020461122b565b60005b9050808303838214611243576112438a8a84846112bf565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c769084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610512565b60606112b78484600085611387565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606082471015611419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c6d565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516114429190611894565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b5091509150611495878383876114a0565b979650505050505050565b6060831561153657825160000361152f5773ffffffffffffffffffffffffffffffffffffffff85163b61152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c6d565b50816112b7565b6112b7838381511561154b5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9190611941565b60006101c0828403121561159257600080fd5b50919050565b6000806101e083850312156115ac57600080fd5b6115b6848461157f565b91506101c083013567ffffffffffffffff8111156115d357600080fd5b8301604081860312156115e557600080fd5b809150509250929050565b60006101c0828403121561160357600080fd5b61033f838361157f565b60006020828403121561161f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461164357600080fd5b9392505050565b60006020828403121561165c57600080fd5b813565ffffffffffff8116811461164357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126116a757600080fd5b83018035915067ffffffffffffffff8211156116c257600080fd5b6020019150368190038213156116d757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156117b257600080fd5b5051919050565b6000602082840312156117cb57600080fd5b813560ff8116811461164357600080fd5b80151581146117ea57600080fd5b50565b6000602082840312156117ff57600080fd5b8135611643816117dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156103425761034261180a565b60006020828403121561185e57600080fd5b813561ffff8116811461164357600080fd5b60005b8381101561188b578181015183820152602001611873565b50506000910152565b600082516118a6818460208701611870565b9190910192915050565b6000602082840312156118c257600080fd5b8151611643816117dc565b61ffff8281168282160390808211156118e8576118e861180a565b5092915050565b80820281158282048414176103425761034261180a565b60008261193c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6020815260008251806020840152611960816040850160208701611870565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202b55d2f11aa7f1395a3e9c79ad5594ecdb6d8158214c767aed2d3da3a5500d1264736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, @@ -261,6 +357,11 @@ { "notice": "The swap fee is over the maximum allowed" } + ], + "PermitForEthToken()": [ + { + "notice": "A function expecting a permit was used when the input token is ETH" + } ] }, "kind": "user", diff --git a/packages/hardhat/deployments/arbitrum/Stargate.json b/packages/hardhat/deployments/arbitrum/Stargate.json index b5fc0ae8..43593d24 100644 --- a/packages/hardhat/deployments/arbitrum/Stargate.json +++ b/packages/hardhat/deployments/arbitrum/Stargate.json @@ -1,5 +1,5 @@ { - "address": "0xd0D1EDc96c8492fd8A4D03300Bc05D3cB799ffa0", + "address": "0xC337BF112b929078b2BC101696CBE796dcCDdD96", "abi": [ { "inputs": [ @@ -124,6 +124,76 @@ "stateMutability": "payable", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint160", + "name": "amountIn", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "amountOutExpected", + "type": "uint160" + }, + { + "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": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "srcPoolId", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "dstPoolId", + "type": "uint8" + } + ], + "internalType": "struct IStargate.JumpTokenParams", + "name": "params", + "type": "tuple" + } + ], + "name": "stargateJumpToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -206,34 +276,34 @@ "type": "tuple" } ], - "name": "stargateJumpToken", + "name": "stargateJumpTokenPermit", "outputs": [], "stateMutability": "payable", "type": "function" } ], - "transactionHash": "0xc1d95908d756e954bde3c8df3eb2591d0e450dcd9e3c8c36902264692c59f5c0", + "transactionHash": "0x6341f1f6aeeacf16f35317637187cbdb8c4f5af61b42305603310bdda58db921", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xd0D1EDc96c8492fd8A4D03300Bc05D3cB799ffa0", + "contractAddress": "0xC337BF112b929078b2BC101696CBE796dcCDdD96", "transactionIndex": 1, - "gasUsed": "3823630", + "gasUsed": "11815732", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x25e4cf148a16367e64995b428b8e80d62fbde4f92ddc7eb46e10df073389015d", - "transactionHash": "0xc1d95908d756e954bde3c8df3eb2591d0e450dcd9e3c8c36902264692c59f5c0", + "blockHash": "0xd54887988939ab5b607e81bcafc64ec130164e6a17ef555774271b13698cf77a", + "transactionHash": "0x6341f1f6aeeacf16f35317637187cbdb8c4f5af61b42305603310bdda58db921", "logs": [], - "blockNumber": 141960561, - "cumulativeGasUsed": "3823630", + "blockNumber": 147606656, + "cumulativeGasUsed": "11815732", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpNativeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"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\":\"stargateJumpToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Stargate.sol\":\"Stargate\"},\"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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract Stargate is IStargate {\\n using SafeERC20 for IERC20;\\n\\n function stargateJumpToken(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.token,\\n amount: 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 // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n uint160(params.amountIn),\\n params.token\\n );\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.token,\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n // NOTE: This lookup is spending 319 gas\\n IStargateRouter stargateRouter = IStargateRouter(\\n LibWarp.state().stargateComposer.stargateRouter()\\n );\\n\\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\\n\\n unchecked {\\n stargateRouter.swap{value: msg.value}({\\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\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n address(0),\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n unchecked {\\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n}\\n\",\"keccak256\":\"0x384ff4fd006f55fd52c6532724722c9d8709db7760e8296c8a9447a19bd148f1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/IStargate.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\n\\ninterface IStargate is ILibStarVault {\\n error InsufficientEthValue();\\n\\n struct JumpTokenParams {\\n address token;\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n struct JumpNativeParams {\\n /**\\n * The amount in is passed to distinguish the amount to bridge from the fee\\n */\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n function stargateJumpToken(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\\n}\\n\",\"keccak256\":\"0x4464ecac16a3c449c8f7983ac21ba54a44ac02194baa590c480b6ffc1cddd478\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b5061148c806100206000396000f3fe6080604052600436106100295760003560e01c806329859a061461002e578063c2bee2af14610043575b600080fd5b61004161003c366004610fca565b610056565b005b610041610051366004611029565b610618565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100b760208a018a611067565b73ffffffffffffffffffffffffffffffffffffffff1681526020018860200160208101906100e59190611067565b73ffffffffffffffffffffffffffffffffffffffff16815260200161011060e08a0160c08b0161108b565b65ffffffffffff9081168252883516602091820152908252309082015260400161014060e0880160c0890161108b565b65ffffffffffff16905261015760208601866110b3565b6040518563ffffffff1660e01b8152600401610176949392919061111f565b600060405180830381600087803b15801561019057600080fd5b505af11580156101a4573d6000803e3d6000fd5b505050506101cf7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633306102006040870160208801611067565b61020d6020880188611067565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561028b57600080fd5b505af115801561029f573d6000803e3d6000fd5b50505050600061032d8360e00160208101906102bb9190611067565b6102c86020860186611067565b6102d860c0870160a088016111e1565b61ffff166102ec6040880160208901611067565b73ffffffffffffffffffffffffffffffffffffffff166103126040890160208a01611067565b73ffffffffffffffffffffffffffffffffffffffff16610905565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190611205565b905061041581836103f86020880188611067565b73ffffffffffffffffffffffffffffffffffffffff1691906109be565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc34610444610120880161010089016111e1565b61045661014089016101208a01611222565b6104686101608a016101408b01611222565b33888061047b60408e0160208f01611067565b73ffffffffffffffffffffffffffffffffffffffff16036104a260608e0160408f01611067565b73ffffffffffffffffffffffffffffffffffffffff16116104c4576000610534565b6105348a8d60200160208101906104db9190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d60400160208101906105059190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d608001602081019061052f91906111e1565b610aee565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508d60600160208101906105739190611067565b6040516020016105ae919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016105e09897969594939291906112b3565b6000604051808303818588803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050505050505050565b6106256020820182611067565b73ffffffffffffffffffffffffffffffffffffffff16341015610674576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106cf61068960e0840160c08501611067565b600061069b60a08601608087016111e1565b61ffff166106ac6020870187611067565b73ffffffffffffffffffffffffffffffffffffffff166103126020880188611067565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261071d6020860186611067565b73ffffffffffffffffffffffffffffffffffffffff16033403610747610100860160e087016111e1565b61075961012087016101008801611222565b61076b61014088016101208901611222565b33878061077b60208c018c611067565b73ffffffffffffffffffffffffffffffffffffffff16036107a260408c0160208d01611067565b73ffffffffffffffffffffffffffffffffffffffff16116107c4576000610823565b610823896107d560208d018d611067565b73ffffffffffffffffffffffffffffffffffffffff16036107fc60408d0160208e01611067565b73ffffffffffffffffffffffffffffffffffffffff160361052f60808d0160608e016111e1565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b60400160208101906108629190611067565b60405160200161089d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016108cf9897969594939291906112b3565b6000604051808303818588803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b50505050505050565b60006107d084111561094c576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561095e575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109945760646032840204610997565b60005b90508083038382146109af576109af8a8a8484610b1e565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610a4a8482610be6565b610ae8576040805173ffffffffffffffffffffffffffffffffffffffff8516602482015260006044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610ade908590610ca7565b610ae88482610ca7565b50505050565b6000612710610afd8382611391565b610b0b9061ffff16856113b3565b610b1591906113ca565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c109190611405565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611421565b8015610c9e575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610dbb9092919063ffffffff16565b9050805160001480610d2a575080806020019051810190610d2a9190611421565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610943565b505050565b6060610dca8484600085610dd2565b949350505050565b606082471015610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610943565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610e8d9190611405565b60006040518083038185875af1925050503d8060008114610eca576040519150601f19603f3d011682016040523d82523d6000602084013e610ecf565b606091505b5091509150610ee087838387610eeb565b979650505050505050565b60608315610f81578251600003610f7a5773ffffffffffffffffffffffffffffffffffffffff85163b610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b5081610dca565b610dca8383815115610f965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109439190611443565b600080828403610180811215610fdf57600080fd5b61016080821215610fef57600080fd5b849350830135905067ffffffffffffffff81111561100c57600080fd5b83016040818603121561101e57600080fd5b809150509250929050565b6000610140828403121561103c57600080fd5b50919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461106457600080fd5b50565b60006020828403121561107957600080fd5b813561108481611042565b9392505050565b60006020828403121561109d57600080fd5b813565ffffffffffff8116811461108457600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110e857600080fd5b83018035915067ffffffffffffffff82111561110357600080fd5b60200191503681900382131561111857600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156111f357600080fd5b813561ffff8116811461108457600080fd5b60006020828403121561121757600080fd5b815161108481611042565b60006020828403121561123457600080fd5b813560ff8116811461108457600080fd5b60005b83811015611260578181015183820152602001611248565b50506000910152565b60008151808452611281816020860160208601611245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c08401528451818401525060208401516101408301526040840151606061016084015261132c610180840182611269565b905082810360e08401526113408185611269565b838103610100850152600081529050602081019b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156113ac576113ac611362565b5092915050565b8082028115828204841417610b1857610b18611362565b600082611400577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251611417818460208701611245565b9190910192915050565b60006020828403121561143357600080fd5b8151801515811461108457600080fd5b602081526000610b15602083018461126956fea2646970667358221220fd4949e43a56ae6a92fdbb921568c2bc2a7013da24304d0b873ce9c5e7515c0264736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806329859a061461002e578063c2bee2af14610043575b600080fd5b61004161003c366004610fca565b610056565b005b610041610051366004611029565b610618565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100b760208a018a611067565b73ffffffffffffffffffffffffffffffffffffffff1681526020018860200160208101906100e59190611067565b73ffffffffffffffffffffffffffffffffffffffff16815260200161011060e08a0160c08b0161108b565b65ffffffffffff9081168252883516602091820152908252309082015260400161014060e0880160c0890161108b565b65ffffffffffff16905261015760208601866110b3565b6040518563ffffffff1660e01b8152600401610176949392919061111f565b600060405180830381600087803b15801561019057600080fd5b505af11580156101a4573d6000803e3d6000fd5b505050506101cf7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633306102006040870160208801611067565b61020d6020880188611067565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561028b57600080fd5b505af115801561029f573d6000803e3d6000fd5b50505050600061032d8360e00160208101906102bb9190611067565b6102c86020860186611067565b6102d860c0870160a088016111e1565b61ffff166102ec6040880160208901611067565b73ffffffffffffffffffffffffffffffffffffffff166103126040890160208a01611067565b73ffffffffffffffffffffffffffffffffffffffff16610905565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190611205565b905061041581836103f86020880188611067565b73ffffffffffffffffffffffffffffffffffffffff1691906109be565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc34610444610120880161010089016111e1565b61045661014089016101208a01611222565b6104686101608a016101408b01611222565b33888061047b60408e0160208f01611067565b73ffffffffffffffffffffffffffffffffffffffff16036104a260608e0160408f01611067565b73ffffffffffffffffffffffffffffffffffffffff16116104c4576000610534565b6105348a8d60200160208101906104db9190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d60400160208101906105059190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d608001602081019061052f91906111e1565b610aee565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508d60600160208101906105739190611067565b6040516020016105ae919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016105e09897969594939291906112b3565b6000604051808303818588803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050505050505050565b6106256020820182611067565b73ffffffffffffffffffffffffffffffffffffffff16341015610674576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106cf61068960e0840160c08501611067565b600061069b60a08601608087016111e1565b61ffff166106ac6020870187611067565b73ffffffffffffffffffffffffffffffffffffffff166103126020880188611067565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261071d6020860186611067565b73ffffffffffffffffffffffffffffffffffffffff16033403610747610100860160e087016111e1565b61075961012087016101008801611222565b61076b61014088016101208901611222565b33878061077b60208c018c611067565b73ffffffffffffffffffffffffffffffffffffffff16036107a260408c0160208d01611067565b73ffffffffffffffffffffffffffffffffffffffff16116107c4576000610823565b610823896107d560208d018d611067565b73ffffffffffffffffffffffffffffffffffffffff16036107fc60408d0160208e01611067565b73ffffffffffffffffffffffffffffffffffffffff160361052f60808d0160608e016111e1565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b60400160208101906108629190611067565b60405160200161089d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016108cf9897969594939291906112b3565b6000604051808303818588803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b50505050505050565b60006107d084111561094c576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561095e575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109945760646032840204610997565b60005b90508083038382146109af576109af8a8a8484610b1e565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610a4a8482610be6565b610ae8576040805173ffffffffffffffffffffffffffffffffffffffff8516602482015260006044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610ade908590610ca7565b610ae88482610ca7565b50505050565b6000612710610afd8382611391565b610b0b9061ffff16856113b3565b610b1591906113ca565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c109190611405565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611421565b8015610c9e575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610dbb9092919063ffffffff16565b9050805160001480610d2a575080806020019051810190610d2a9190611421565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610943565b505050565b6060610dca8484600085610dd2565b949350505050565b606082471015610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610943565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610e8d9190611405565b60006040518083038185875af1925050503d8060008114610eca576040519150601f19603f3d011682016040523d82523d6000602084013e610ecf565b606091505b5091509150610ee087838387610eeb565b979650505050505050565b60608315610f81578251600003610f7a5773ffffffffffffffffffffffffffffffffffffffff85163b610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b5081610dca565b610dca8383815115610f965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109439190611443565b600080828403610180811215610fdf57600080fd5b61016080821215610fef57600080fd5b849350830135905067ffffffffffffffff81111561100c57600080fd5b83016040818603121561101e57600080fd5b809150509250929050565b6000610140828403121561103c57600080fd5b50919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461106457600080fd5b50565b60006020828403121561107957600080fd5b813561108481611042565b9392505050565b60006020828403121561109d57600080fd5b813565ffffffffffff8116811461108457600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110e857600080fd5b83018035915067ffffffffffffffff82111561110357600080fd5b60200191503681900382131561111857600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156111f357600080fd5b813561ffff8116811461108457600080fd5b60006020828403121561121757600080fd5b815161108481611042565b60006020828403121561123457600080fd5b813560ff8116811461108457600080fd5b60005b83811015611260578181015183820152602001611248565b50506000910152565b60008151808452611281816020860160208601611245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c08401528451818401525060208401516101408301526040840151606061016084015261132c610180840182611269565b905082810360e08401526113408185611269565b838103610100850152600081529050602081019b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156113ac576113ac611362565b5092915050565b8082028115828204841417610b1857610b18611362565b600082611400577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251611417818460208701611245565b9190910192915050565b60006020828403121561143357600080fd5b8151801515811461108457600080fd5b602081526000610b15602083018461126956fea2646970667358221220fd4949e43a56ae6a92fdbb921568c2bc2a7013da24304d0b873ce9c5e7515c0264736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpNativeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"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\":\"stargateJumpTokenPermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Stargate.sol\":\"Stargate\"},\"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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract Stargate is IStargate {\\n using SafeERC20 for IERC20;\\n\\n /**\\n * Jump tokens with Stargate with input tokens already moved to this contract\\n */\\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.token,\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n // NOTE: This lookup is spending 319 gas\\n IStargateRouter stargateRouter = IStargateRouter(\\n LibWarp.state().stargateComposer.stargateRouter()\\n );\\n\\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\\n\\n unchecked {\\n stargateRouter.swap{value: msg.value}({\\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\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n\\n function stargateJumpTokenPermit(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.token,\\n amount: 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 // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n uint160(params.amountIn),\\n params.token\\n );\\n\\n stargateJumpTokenInternal(params);\\n }\\n\\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\\n // Transfer tokens from the sender to this contract\\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\\n\\n stargateJumpTokenInternal(params);\\n }\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n address(0),\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n unchecked {\\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6abe4954877eed5b5a9c473441ac11e6f505d6cedc5c1d9489960227c5fb6f84\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/IStargate.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\n\\ninterface IStargate is ILibStarVault {\\n error InsufficientEthValue();\\n\\n struct JumpTokenParams {\\n address token;\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n struct JumpNativeParams {\\n /**\\n * The amount in is passed to distinguish the amount to bridge from the fee\\n */\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\\n\\n function stargateJumpTokenPermit(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\\n}\\n\",\"keccak256\":\"0xb35bd721e5ab9f7cd120a61bdafd807dcebd1cf71f5189662697f47a1f10986c\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506115d1806100206000396000f3fe6080604052600436106100345760003560e01c80638be9f27914610039578063ba2466d41461004e578063c2bee2af14610061575b600080fd5b61004c610047366004611102565b610074565b005b61004c61005c36600461115a565b6102ce565b61004c61006f366004611177565b610330565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100d560208a018a6111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200188602001602081019061010391906111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200161012e60e08a0160c08b016111d0565b65ffffffffffff9081168252883516602091820152908252309082015260400161015e60e0880160c089016111d0565b65ffffffffffff16905261017560208601866111f8565b6040518563ffffffff1660e01b81526004016101949493929190611264565b600060405180830381600087803b1580156101ae57600080fd5b505af11580156101c2573d6000803e3d6000fd5b505050506101ed7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333061021e60408701602088016111ac565b61022b60208801886111ac565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102a957600080fd5b505af11580156102bd573d6000803e3d6000fd5b505050506102ca8261063d565b5050565b61032433306102e360408501602086016111ac565b73ffffffffffffffffffffffffffffffffffffffff1661030660208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff16929190610986565b61032d8161063d565b50565b61033d60208201826111ac565b73ffffffffffffffffffffffffffffffffffffffff1634101561038c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104026103a160e0840160c085016111ac565b60006103b360a0860160808701611326565b61ffff166103c460208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760208801886111ac565b73ffffffffffffffffffffffffffffffffffffffff16610a68565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261045060208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff1603340361047a610100860160e08701611326565b61048c6101208701610100880161134a565b61049e6101408801610120890161134a565b3387806104ae60208c018c6111ac565b73ffffffffffffffffffffffffffffffffffffffff16036104d560408c0160208d016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116104f757600061055b565b61055b8961050860208d018d6111ac565b73ffffffffffffffffffffffffffffffffffffffff160361052f60408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660808d0160608e01611326565b610b21565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b604001602081019061059a91906111ac565b6040516020016105d5919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016106079897969594939291906113db565b6000604051808303818588803b15801561062057600080fd5b505af1158015610634573d6000803e3d6000fd5b50505050505050565b60006106aa610653610100840160e085016111ac565b61066060208501856111ac565b61067060c0860160a08701611326565b61ffff1661068460408701602088016111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760408801602089016111ac565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610761919061148a565b9050610792818361077560208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff169190610b51565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc346107c161012087016101008801611326565b6107d36101408801610120890161134a565b6107e561016089016101408a0161134a565b3388806107f860408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361081f60608d0160408e016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116108415760006108a3565b6108a38a61085560408e0160208f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361087c60608e0160408f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660a08e0160808f01611326565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60600160208101906108e291906111ac565b60405160200161091d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b815260040161094f9897969594939291906113db565b6000604051808303818588803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a629085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610c3d565b50505050565b60006107d0841115610aaf576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610ac1575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610af75760646032840204610afa565b60005b9050808303838214610b1257610b128a8a8484610d51565b50505090910395945050505050565b6000612710610b3083826114d6565b610b3e9061ffff16856114f8565b610b48919061150f565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610bdd8482610e19565b610a625760405173ffffffffffffffffffffffffffffffffffffffff8416602482015260006044820152610c379085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109e0565b610a6284825b6000610c9f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610eda9092919063ffffffff16565b9050805160001480610cc0575080806020019051810190610cc0919061154a565b610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa6565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e43919061156c565b6000604051808303816000865af19150503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5091509150818015610eaf575080511580610eaf575080806020019051810190610eaf919061154a565b8015610ed1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060610ee98484600085610ef1565b949350505050565b606082471015610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fac919061156c565b60006040518083038185875af1925050503d8060008114610fe9576040519150601f19603f3d011682016040523d82523d6000602084013e610fee565b606091505b5091509150610fff8783838761100a565b979650505050505050565b606083156110a05782516000036110995773ffffffffffffffffffffffffffffffffffffffff85163b611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa6565b5081610ee9565b610ee983838151156110b55781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa69190611588565b600061016082840312156110fc57600080fd5b50919050565b600080610180838503121561111657600080fd5b61112084846110e9565b915061016083013567ffffffffffffffff81111561113d57600080fd5b83016040818603121561114f57600080fd5b809150509250929050565b6000610160828403121561116d57600080fd5b610b4883836110e9565b600061014082840312156110fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461032d57600080fd5b6000602082840312156111be57600080fd5b81356111c98161118a565b9392505050565b6000602082840312156111e257600080fd5b813565ffffffffffff811681146111c957600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261122d57600080fd5b83018035915067ffffffffffffffff82111561124857600080fd5b60200191503681900382131561125d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60006020828403121561133857600080fd5b813561ffff811681146111c957600080fd5b60006020828403121561135c57600080fd5b813560ff811681146111c957600080fd5b60005b83811015611388578181015183820152602001611370565b50506000910152565b600081518084526113a981602086016020860161136d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c084015284518184015250602084015161014083015260408401516060610160840152611454610180840182611391565b905082810360e08401526114688185611391565b838103610100850152600081529050602081019b9a5050505050505050505050565b60006020828403121561149c57600080fd5b81516111c98161118a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156114f1576114f16114a7565b5092915050565b8082028115828204841417610b4b57610b4b6114a7565b600082611545577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561155c57600080fd5b815180151581146111c957600080fd5b6000825161157e81846020870161136d565b9190910192915050565b602081526000610b48602083018461139156fea26469706673582212208328d8149ca8eb632152123f06714fc50d6667b0823eba29b328ace315d4e37464736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c80638be9f27914610039578063ba2466d41461004e578063c2bee2af14610061575b600080fd5b61004c610047366004611102565b610074565b005b61004c61005c36600461115a565b6102ce565b61004c61006f366004611177565b610330565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100d560208a018a6111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200188602001602081019061010391906111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200161012e60e08a0160c08b016111d0565b65ffffffffffff9081168252883516602091820152908252309082015260400161015e60e0880160c089016111d0565b65ffffffffffff16905261017560208601866111f8565b6040518563ffffffff1660e01b81526004016101949493929190611264565b600060405180830381600087803b1580156101ae57600080fd5b505af11580156101c2573d6000803e3d6000fd5b505050506101ed7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333061021e60408701602088016111ac565b61022b60208801886111ac565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102a957600080fd5b505af11580156102bd573d6000803e3d6000fd5b505050506102ca8261063d565b5050565b61032433306102e360408501602086016111ac565b73ffffffffffffffffffffffffffffffffffffffff1661030660208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff16929190610986565b61032d8161063d565b50565b61033d60208201826111ac565b73ffffffffffffffffffffffffffffffffffffffff1634101561038c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104026103a160e0840160c085016111ac565b60006103b360a0860160808701611326565b61ffff166103c460208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760208801886111ac565b73ffffffffffffffffffffffffffffffffffffffff16610a68565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261045060208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff1603340361047a610100860160e08701611326565b61048c6101208701610100880161134a565b61049e6101408801610120890161134a565b3387806104ae60208c018c6111ac565b73ffffffffffffffffffffffffffffffffffffffff16036104d560408c0160208d016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116104f757600061055b565b61055b8961050860208d018d6111ac565b73ffffffffffffffffffffffffffffffffffffffff160361052f60408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660808d0160608e01611326565b610b21565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b604001602081019061059a91906111ac565b6040516020016105d5919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016106079897969594939291906113db565b6000604051808303818588803b15801561062057600080fd5b505af1158015610634573d6000803e3d6000fd5b50505050505050565b60006106aa610653610100840160e085016111ac565b61066060208501856111ac565b61067060c0860160a08701611326565b61ffff1661068460408701602088016111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760408801602089016111ac565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610761919061148a565b9050610792818361077560208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff169190610b51565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc346107c161012087016101008801611326565b6107d36101408801610120890161134a565b6107e561016089016101408a0161134a565b3388806107f860408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361081f60608d0160408e016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116108415760006108a3565b6108a38a61085560408e0160208f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361087c60608e0160408f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660a08e0160808f01611326565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60600160208101906108e291906111ac565b60405160200161091d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b815260040161094f9897969594939291906113db565b6000604051808303818588803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a629085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610c3d565b50505050565b60006107d0841115610aaf576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610ac1575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610af75760646032840204610afa565b60005b9050808303838214610b1257610b128a8a8484610d51565b50505090910395945050505050565b6000612710610b3083826114d6565b610b3e9061ffff16856114f8565b610b48919061150f565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610bdd8482610e19565b610a625760405173ffffffffffffffffffffffffffffffffffffffff8416602482015260006044820152610c379085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109e0565b610a6284825b6000610c9f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610eda9092919063ffffffff16565b9050805160001480610cc0575080806020019051810190610cc0919061154a565b610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa6565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e43919061156c565b6000604051808303816000865af19150503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5091509150818015610eaf575080511580610eaf575080806020019051810190610eaf919061154a565b8015610ed1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060610ee98484600085610ef1565b949350505050565b606082471015610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fac919061156c565b60006040518083038185875af1925050503d8060008114610fe9576040519150601f19603f3d011682016040523d82523d6000602084013e610fee565b606091505b5091509150610fff8783838761100a565b979650505050505050565b606083156110a05782516000036110995773ffffffffffffffffffffffffffffffffffffffff85163b611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa6565b5081610ee9565b610ee983838151156110b55781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa69190611588565b600061016082840312156110fc57600080fd5b50919050565b600080610180838503121561111657600080fd5b61112084846110e9565b915061016083013567ffffffffffffffff81111561113d57600080fd5b83016040818603121561114f57600080fd5b809150509250929050565b6000610160828403121561116d57600080fd5b610b4883836110e9565b600061014082840312156110fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461032d57600080fd5b6000602082840312156111be57600080fd5b81356111c98161118a565b9392505050565b6000602082840312156111e257600080fd5b813565ffffffffffff811681146111c957600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261122d57600080fd5b83018035915067ffffffffffffffff82111561124857600080fd5b60200191503681900382131561125d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60006020828403121561133857600080fd5b813561ffff811681146111c957600080fd5b60006020828403121561135c57600080fd5b813560ff811681146111c957600080fd5b60005b83811015611388578181015183820152602001611370565b50506000910152565b600081518084526113a981602086016020860161136d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c084015284518184015250602084015161014083015260408401516060610160840152611454610180840182611391565b905082810360e08401526114688185611391565b838103610100850152600081529050602081019b9a5050505050505050505050565b60006020828403121561149c57600080fd5b81516111c98161118a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156114f1576114f16114a7565b5092915050565b8082028115828204841417610b4b57610b4b6114a7565b600082611545577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561155c57600080fd5b815180151581146111c957600080fd5b6000825161157e81846020870161136d565b9190910192915050565b602081526000610b48602083018461139156fea26469706673582212208328d8149ca8eb632152123f06714fc50d6667b0823eba29b328ace315d4e37464736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/UniV2LikeFacet.json b/packages/hardhat/deployments/arbitrum/UniV2LikeFacet.json index 199481ec..ec71a05f 100644 --- a/packages/hardhat/deployments/arbitrum/UniV2LikeFacet.json +++ b/packages/hardhat/deployments/arbitrum/UniV2LikeFacet.json @@ -1,5 +1,5 @@ { - "address": "0x7B02C974D975ca1fcA6a48435cBafB13ADd5895a", + "address": "0x9B6f95C08C66DCdE19dE551809Ad300Fde6CB97b", "abi": [ { "inputs": [], @@ -116,6 +116,77 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV2LikeExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -193,7 +264,83 @@ "type": "tuple" } ], - "name": "uniswapV2LikeExactInput", + "name": "uniswapV2LikeExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV2LikeExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -286,7 +433,7 @@ "type": "tuple" } ], - "name": "uniswapV2LikeExactInputSingle", + "name": "uniswapV2LikeExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -294,32 +441,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0x58c8074cc207380030895b10704a22fa38d695064601e30245f7ae0d9c670e84", + "transactionHash": "0x13aabcfe05bdc420738a2a8132845907a29a8a9466805113b6ea9102964bf2d4", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x7B02C974D975ca1fcA6a48435cBafB13ADd5895a", + "contractAddress": "0x9B6f95C08C66DCdE19dE551809Ad300Fde6CB97b", "transactionIndex": 1, - "gasUsed": "6160577", + "gasUsed": "18984331", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf4d3f0535e402d7f88a269d89bbab10b891d176222b68b5dc87d65d200d81ad2", - "transactionHash": "0x58c8074cc207380030895b10704a22fa38d695064601e30245f7ae0d9c670e84", + "blockHash": "0x4cc7ef1241d8f99cc000be04ecf5baa0d7eff3b730c4f12f0c2c996082f0e64d", + "transactionHash": "0x13aabcfe05bdc420738a2a8132845907a29a8a9466805113b6ea9102964bf2d4", "logs": [], - "blockNumber": 141960298, - "cumulativeGasUsed": "6160577", + "blockNumber": 147606403, + "cumulativeGasUsed": "18984331", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 9, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokens[0],\\n isToEth ? address(0) : params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x4d807156203d016fd7fe1ff2dd503972c0f07d9d8f1b0794aca4459c1ea03b7a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Like is ILibStarVault, ILibWarp {\\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\":\"0x80c9be72cf89c5673f0acfb44d672ae65e86062906042a31007a9737c9e1a3db\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612542806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611e34565b610066565b60405190815260200160405180910390f35b610041610061366004612036565b6109e7565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101949190612176565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb6121fd565b0497505061030189602001518a60a00151611569565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611599565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61222c565b6040518563ffffffff1660e01b81526004016104db9493929190612298565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b505050506101008a01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190612176565b90508481108061076b57506107688986612389565b81105b156107a2576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c48b60c001518c61010001518d6080015161ffff168e602001518d61162b565b985085156108f35787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108ad576040519150601f19603f3d011682016040523d82523d6000602084013e6108b2565b606091505b50509050806108ed576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610927565b6109278b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b85610937578a610100015161093a565b60005b73ffffffffffffffffffffffffffffffffffffffff168761095f578b60e00151610962565b60005b73ffffffffffffffffffffffffffffffffffffffff168c60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38e600001518d6040516109d1929190918252602082015260400190565b60405180910390a4505050505050505092915050565b60008260c0015165ffffffffffff16421115610a2f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1092916000918291908290610a7557610a7561239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610ac657610ac661239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610ba4578761010001518481518110610b0557610b0561239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9f9190612176565b610ba6565b475b90506000610bc889604001518a600001518b61010001518c61012001516116e4565b9050610bdc89602001518a60800151611569565b8160018351610beb91906123cb565b81518110610bfb57610bfb61239c565b60200260200101511015610c3b576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610d725788513414610c7b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b5050505050610d6d896101200151600081518110610d1b57610d1b61239c565b60200260200101518a600001518b6101000151600081518110610d4057610d4061239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b610fc7565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610de157610de161239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610e87919061222c565b6040518563ffffffff1660e01b8152600401610ea69493929190612298565b600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610f1557610f1561239c565b60200260200101518c600001518d6101000151600081518110610f3a57610f3a61239c565b60200260200101516040518563ffffffff1660e01b8152600401610f94949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610fae57600080fd5b505af1158015610fc2573d6000803e3d6000fd5b505050505b60005b858110156111d0576000610fdf826001612389565b905060008b61010001518281518110610ffa57610ffa61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c6101000151848151811061102f5761102f61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061105957600061105c565b60015b9050600060028d61010001515161107391906123cb565b841061107f573061109f565b8c610120015183815181106110965761109661239c565b60200260200101515b90508c610120015184815181106110b8576110b861239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836110ff578685815181106110f2576110f261239c565b6020026020010151611102565b60005b8461110e576000611129565b8786815181106111205761112061239c565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156111a957600080fd5b505af11580156111bd573d6000803e3d6000fd5b505060019095019450610fca9350505050565b50600089610100015186815181106111ea576111ea61239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190612176565b90508281108061129c57506112998884612389565b81105b156112d3576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113278a60e001518b610100015188815181106112f2576112f261239c565b60200260200101518c60a0015161ffff168d60200151868b8151811061131a5761131a61239c565b602002602001015161162b565b975083156114565786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611410576040519150601f19603f3d011682016040523d82523d6000602084013e611415565b606091505b5050905080611450576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611476565b6114768a60600151898c61010001518981518110610d4057610d4061239c565b8361149f5789610100015186815181106114925761149261239c565b60200260200101516114a2565b60005b73ffffffffffffffffffffffffffffffffffffffff16856114e2578a61010001516000815181106114d5576114d561239c565b60200260200101516114e5565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60e0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c604051611554929190918252602082015260400190565b60405180910390a45050505050505092915050565b600061271061157883826123de565b6115869061ffff1685612400565b6115909190612417565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611626908490611919565b505050565b60006107d0841115611672576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611684575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116ba57606460328402046116bd565b60005b90508083038382146116d5576116d58a8a8484611a28565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561170457611704611cff565b60405190808252806020026020018201604052801561172d578160200160208202803683370190505b50915084826000815181106117445761174461239c565b60200260200101818152505060005b8181101561190f57600085828151811061176f5761176f61239c565b602002602001015190506000868360016117899190612389565b815181106117995761179961239c565b6020026020010151905060008984815181106117b7576117b761239c565b60200260200101516127106117cc91906123de565b61ffff1690506000808886815181106117e7576117e761239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185d91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156118b857905b828b0282612710020181848d0202816118d3576118d36121fd565b049a508a886118e3886001612389565b815181106118f3576118f361239c565b6020908102919091010152505060019093019250611753915050565b5050949350505050565b600061197b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611af09092919063ffffffff16565b905080516000148061199c57508080602001905181019061199c9190612452565b611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611669565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611aff8484600085611b07565b949350505050565b606082471015611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611669565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bc2919061249f565b60006040518083038185875af1925050503d8060008114611bff576040519150601f19603f3d011682016040523d82523d6000602084013e611c04565b606091505b5091509150611c1587838387611c20565b979650505050505050565b60608315611cb6578251600003611caf5773ffffffffffffffffffffffffffffffffffffffff85163b611caf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611669565b5081611aff565b611aff8383815115611ccb5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166991906124bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611d5257611d52611cff565b60405290565b604051610140810167ffffffffffffffff81118282101715611d5257611d52611cff565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc357611dc3611cff565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611def57600080fd5b919050565b803561ffff81168114611def57600080fd5b803565ffffffffffff81168114611def57600080fd5b600060408284031215611e2e57600080fd5b50919050565b600080828403610180811215611e4957600080fd5b61016080821215611e5957600080fd5b611e61611d2e565b91508435825260208501356020830152611e7d60408601611dcb565b6040830152611e8e60608601611dcb565b6060830152611e9f60808601611df4565b6080830152611eb060a08601611df4565b60a0830152611ec160c08601611dcb565b60c0830152611ed260e08601611dcb565b60e0830152610100611ee5818701611dcb565b90830152610120611ef7868201611df4565b90830152610140611f09868201611e06565b9083015290925083013567ffffffffffffffff811115611f2857600080fd5b611f3485828601611e1c565b9150509250929050565b600067ffffffffffffffff821115611f5857611f58611cff565b5060051b60200190565b600082601f830112611f7357600080fd5b81356020611f88611f8383611f3e565b611d7c565b82815260059290921b84018101918181019086841115611fa757600080fd5b8286015b84811015611fc957611fbc81611df4565b8352918301918301611fab565b509695505050505050565b600082601f830112611fe557600080fd5b81356020611ff5611f8383611f3e565b82815260059290921b8401810191818101908684111561201457600080fd5b8286015b84811015611fc95761202981611dcb565b8352918301918301612018565b6000806040838503121561204957600080fd5b823567ffffffffffffffff8082111561206157600080fd5b90840190610140828703121561207657600080fd5b61207e611d58565b823581526020830135602082015260408301358281111561209e57600080fd5b6120aa88828601611f62565b6040830152506120bc60608401611dcb565b60608201526120cd60808401611df4565b60808201526120de60a08401611df4565b60a08201526120ef60c08401611e06565b60c082015261210060e08401611dcb565b60e0820152610100808401358381111561211957600080fd5b61212589828701611fd4565b828401525050610120808401358381111561213f57600080fd5b61214b89828701611fd4565b82840152505080945050602085013591508082111561216957600080fd5b50611f3485828601611e1c565b60006020828403121561218857600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611def57600080fd5b6000806000606084860312156121c257600080fd5b6121cb8461218f565b92506121d96020850161218f565b9150604084015163ffffffff811681146121f257600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261226157600080fd5b83018035915067ffffffffffffffff82111561227c57600080fd5b60200191503681900382131561229157600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156115935761159361235a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b818103818111156115935761159361235a565b61ffff8281168282160390808211156123f9576123f961235a565b5092915050565b80820281158282048414176115935761159361235a565b60008261244d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561246457600080fd5b8151801515811461247457600080fd5b9392505050565b60005b8381101561249657818101518382015260200161247e565b50506000910152565b600082516124b181846020870161247b565b9190910192915050565b60208152600082518060208401526124da81604085016020870161247b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220200d00eba2c244bcc4394586e11bed52f1bde27d737f84e6823312ec945bdf2064736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611e34565b610066565b60405190815260200160405180910390f35b610041610061366004612036565b6109e7565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101949190612176565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb6121fd565b0497505061030189602001518a60a00151611569565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611599565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61222c565b6040518563ffffffff1660e01b81526004016104db9493929190612298565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b505050506101008a01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190612176565b90508481108061076b57506107688986612389565b81105b156107a2576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c48b60c001518c61010001518d6080015161ffff168e602001518d61162b565b985085156108f35787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108ad576040519150601f19603f3d011682016040523d82523d6000602084013e6108b2565b606091505b50509050806108ed576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610927565b6109278b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b85610937578a610100015161093a565b60005b73ffffffffffffffffffffffffffffffffffffffff168761095f578b60e00151610962565b60005b73ffffffffffffffffffffffffffffffffffffffff168c60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38e600001518d6040516109d1929190918252602082015260400190565b60405180910390a4505050505050505092915050565b60008260c0015165ffffffffffff16421115610a2f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1092916000918291908290610a7557610a7561239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610ac657610ac661239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610ba4578761010001518481518110610b0557610b0561239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9f9190612176565b610ba6565b475b90506000610bc889604001518a600001518b61010001518c61012001516116e4565b9050610bdc89602001518a60800151611569565b8160018351610beb91906123cb565b81518110610bfb57610bfb61239c565b60200260200101511015610c3b576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610d725788513414610c7b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b5050505050610d6d896101200151600081518110610d1b57610d1b61239c565b60200260200101518a600001518b6101000151600081518110610d4057610d4061239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b610fc7565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610de157610de161239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610e87919061222c565b6040518563ffffffff1660e01b8152600401610ea69493929190612298565b600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610f1557610f1561239c565b60200260200101518c600001518d6101000151600081518110610f3a57610f3a61239c565b60200260200101516040518563ffffffff1660e01b8152600401610f94949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610fae57600080fd5b505af1158015610fc2573d6000803e3d6000fd5b505050505b60005b858110156111d0576000610fdf826001612389565b905060008b61010001518281518110610ffa57610ffa61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c6101000151848151811061102f5761102f61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061105957600061105c565b60015b9050600060028d61010001515161107391906123cb565b841061107f573061109f565b8c610120015183815181106110965761109661239c565b60200260200101515b90508c610120015184815181106110b8576110b861239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836110ff578685815181106110f2576110f261239c565b6020026020010151611102565b60005b8461110e576000611129565b8786815181106111205761112061239c565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156111a957600080fd5b505af11580156111bd573d6000803e3d6000fd5b505060019095019450610fca9350505050565b50600089610100015186815181106111ea576111ea61239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190612176565b90508281108061129c57506112998884612389565b81105b156112d3576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113278a60e001518b610100015188815181106112f2576112f261239c565b60200260200101518c60a0015161ffff168d60200151868b8151811061131a5761131a61239c565b602002602001015161162b565b975083156114565786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611410576040519150601f19603f3d011682016040523d82523d6000602084013e611415565b606091505b5050905080611450576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611476565b6114768a60600151898c61010001518981518110610d4057610d4061239c565b8361149f5789610100015186815181106114925761149261239c565b60200260200101516114a2565b60005b73ffffffffffffffffffffffffffffffffffffffff16856114e2578a61010001516000815181106114d5576114d561239c565b60200260200101516114e5565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60e0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c604051611554929190918252602082015260400190565b60405180910390a45050505050505092915050565b600061271061157883826123de565b6115869061ffff1685612400565b6115909190612417565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611626908490611919565b505050565b60006107d0841115611672576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611684575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116ba57606460328402046116bd565b60005b90508083038382146116d5576116d58a8a8484611a28565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561170457611704611cff565b60405190808252806020026020018201604052801561172d578160200160208202803683370190505b50915084826000815181106117445761174461239c565b60200260200101818152505060005b8181101561190f57600085828151811061176f5761176f61239c565b602002602001015190506000868360016117899190612389565b815181106117995761179961239c565b6020026020010151905060008984815181106117b7576117b761239c565b60200260200101516127106117cc91906123de565b61ffff1690506000808886815181106117e7576117e761239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185d91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156118b857905b828b0282612710020181848d0202816118d3576118d36121fd565b049a508a886118e3886001612389565b815181106118f3576118f361239c565b6020908102919091010152505060019093019250611753915050565b5050949350505050565b600061197b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611af09092919063ffffffff16565b905080516000148061199c57508080602001905181019061199c9190612452565b611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611669565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611aff8484600085611b07565b949350505050565b606082471015611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611669565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bc2919061249f565b60006040518083038185875af1925050503d8060008114611bff576040519150601f19603f3d011682016040523d82523d6000602084013e611c04565b606091505b5091509150611c1587838387611c20565b979650505050505050565b60608315611cb6578251600003611caf5773ffffffffffffffffffffffffffffffffffffffff85163b611caf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611669565b5081611aff565b611aff8383815115611ccb5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166991906124bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611d5257611d52611cff565b60405290565b604051610140810167ffffffffffffffff81118282101715611d5257611d52611cff565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc357611dc3611cff565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611def57600080fd5b919050565b803561ffff81168114611def57600080fd5b803565ffffffffffff81168114611def57600080fd5b600060408284031215611e2e57600080fd5b50919050565b600080828403610180811215611e4957600080fd5b61016080821215611e5957600080fd5b611e61611d2e565b91508435825260208501356020830152611e7d60408601611dcb565b6040830152611e8e60608601611dcb565b6060830152611e9f60808601611df4565b6080830152611eb060a08601611df4565b60a0830152611ec160c08601611dcb565b60c0830152611ed260e08601611dcb565b60e0830152610100611ee5818701611dcb565b90830152610120611ef7868201611df4565b90830152610140611f09868201611e06565b9083015290925083013567ffffffffffffffff811115611f2857600080fd5b611f3485828601611e1c565b9150509250929050565b600067ffffffffffffffff821115611f5857611f58611cff565b5060051b60200190565b600082601f830112611f7357600080fd5b81356020611f88611f8383611f3e565b611d7c565b82815260059290921b84018101918181019086841115611fa757600080fd5b8286015b84811015611fc957611fbc81611df4565b8352918301918301611fab565b509695505050505050565b600082601f830112611fe557600080fd5b81356020611ff5611f8383611f3e565b82815260059290921b8401810191818101908684111561201457600080fd5b8286015b84811015611fc95761202981611dcb565b8352918301918301612018565b6000806040838503121561204957600080fd5b823567ffffffffffffffff8082111561206157600080fd5b90840190610140828703121561207657600080fd5b61207e611d58565b823581526020830135602082015260408301358281111561209e57600080fd5b6120aa88828601611f62565b6040830152506120bc60608401611dcb565b60608201526120cd60808401611df4565b60808201526120de60a08401611df4565b60a08201526120ef60c08401611e06565b60c082015261210060e08401611dcb565b60e0820152610100808401358381111561211957600080fd5b61212589828701611fd4565b828401525050610120808401358381111561213f57600080fd5b61214b89828701611fd4565b82840152505080945050602085013591508082111561216957600080fd5b50611f3485828601611e1c565b60006020828403121561218857600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611def57600080fd5b6000806000606084860312156121c257600080fd5b6121cb8461218f565b92506121d96020850161218f565b9150604084015163ffffffff811681146121f257600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261226157600080fd5b83018035915067ffffffffffffffff82111561227c57600080fd5b60200191503681900382131561229157600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156115935761159361235a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b818103818111156115935761159361235a565b61ffff8281168282160390808211156123f9576123f961235a565b5092915050565b80820281158282048414176115935761159361235a565b60008261244d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561246457600080fd5b8151801515811461247457600080fd5b9392505050565b60005b8381101561249657818101518382015260200161247e565b50506000910152565b600082516124b181846020870161247b565b9190910192915050565b60208152600082518060208401526124da81604085016020870161247b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220200d00eba2c244bcc4394586e11bed52f1bde27d737f84e6823312ec945bdf2064736f6c63430008130033", + "numDeployments": 10, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"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\":\"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\":\"uniswapV2LikeExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"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\":\"uniswapV2LikeExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\\n * NOTE: The tokens must already have been moved to the first pool\\n */\\n function uniswapV2LikeExactInputSingleInternal(\\n ExactInputSingleParams memory params\\n ) internal returns (uint256 amountOut) {\\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\\n } else {\\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\\n }\\n\\n return uniswapV2LikeExactInputSingleInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 the pool\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n params.pool,\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n\\n return uniswapV2LikeExactInputSingleInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputInternal(\\n ExactInputParams calldata params\\n ) internal returns (uint256 amountOut) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n address[] memory tokens = params.tokens;\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = tokens[0] == address(0);\\n bool isToEth = tokens[poolLength] == address(0);\\n\\n if (isFromEth) {\\n tokens[0] = address(s.weth);\\n }\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : tokens[0],\\n isToEth ? address(0) : tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokens[0] == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\\n }\\n\\n return uniswapV2LikeExactInputInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\n // Permit tokens / set allowance\\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n\\n return uniswapV2LikeExactInputInternal(params);\\n }\\n}\\n\",\"keccak256\":\"0x2264d60e017f7ec8aa13691a2cabd116d785824587c832a5cb8dbaa5336599c1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Like is ILibStarVault, ILibWarp {\\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 ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInputSinglePermit(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInputPermit(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x61257f389c4a69c463baafad1a008ed2e9d68936a7e4a2cbe5a0cdc60df61e40\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b5061299a806100206000396000f3fe60806040526004361061003f5760003560e01c806311f1fdef14610044578063baa8ed3514610076578063c83ee48414610089578063d1b72bc41461009c575b600080fd5b34801561005057600080fd5b5061006461005f366004612268565b6100bc565b60405190815260200160405180910390f35b6100646100843660046122b9565b610319565b6100646100973660046122e9565b61052d565b3480156100a857600080fd5b506100646100b736600461231e565b610766565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610126906101008c01908c016123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161015d6101608b016101408c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161018f61016089016101408a016123d2565b65ffffffffffff1690526101a660208701876123ed565b6040518563ffffffff1660e01b81526004016101c59493929190612459565b600060405180830381600087803b1580156101df57600080fd5b505af11580156101f3573d6000803e3d6000fd5b5050505061021e7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c785163361024e60808701606088016123a1565b8635610261610100890160e08a016123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102df57600080fd5b505af11580156102f3573d6000803e3d6000fd5b505050506103108380360381019061030b91906125ad565b610a0c565b90505b92915050565b600061032d610160830161014084016123d2565b65ffffffffffff1642111561036e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610381610100840160e085016123a1565b73ffffffffffffffffffffffffffffffffffffffff16036104d657348235146103d6576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561046257600080fd5b505af1158015610476573d6000803e3d6000fd5b50505050506104d182606001602081019061049191906123a1565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff169084356110ca565b61051b565b61051b336104ea60808501606086016123a1565b84356104fd610100870160e088016123a1565b73ffffffffffffffffffffffffffffffffffffffff169291906111a3565b61031361030b368490038401846125ad565b600061053f60e0830160c084016123d2565b65ffffffffffff16421115610580576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610590610100840184612679565b60008181106105a1576105a16126e1565b90506020020160208101906105b691906123a1565b73ffffffffffffffffffffffffffffffffffffffff16036106ef573482351461060b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561069757600080fd5b505af11580156106ab573d6000803e3d6000fd5b50505050506106ea828061012001906106c49190612679565b60008181106106d5576106d56126e1565b905060200201602081019061049191906123a1565b61075d565b61075d33610701610120850185612679565b6000818110610712576107126126e1565b905060200201602081019061072791906123a1565b8435610737610100870187612679565b6000818110610748576107486126e1565b90506020020160208101906104fd91906123a1565b61031382611207565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915260009173ffffffffffffffffffffffffffffffffffffffff1690632b67b5709033908060608101806107c96101008b018b612679565b60008181106107da576107da6126e1565b90506020020160208101906107ef91906123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161082460e08b0160c08c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161085460e0890160c08a016123d2565b65ffffffffffff16905261086b60208701876123ed565b6040518563ffffffff1660e01b815260040161088a9493929190612459565b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506108e37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633610911610120870187612679565b6000818110610922576109226126e1565b905060200201602081019061093791906123a1565b8635610947610100890189612679565b6000818110610958576109586126e1565b905060200201602081019061096d91906123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050505061031083611207565b60e08101516101008201516000917f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff918216159116158381610af8576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af39190612710565b610afa565b475b90508215610b2057835473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8115610b4557835473ffffffffffffffffffffffffffffffffffffffff166101008701525b600080876060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915087610100015173ffffffffffffffffffffffffffffffffffffffff168860e0015173ffffffffffffffffffffffffffffffffffffffff161115610c1f57905b610120880151885161ffff6127109283031691840290820290810190830281610c4a57610c4a612797565b04975050610c6088602001518960a00151611b42565b871015610c99576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1610610cde576000610ce1565b60015b9050886060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610d0e5789610d11565b60005b83610d1d576000610d1f565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015610d8957600080fd5b505af1158015610d9d573d6000803e3d6000fd5b505050506101008901516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190612710565b905084811080610e4f5750610e4c89866127f5565b81105b15610e86576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea88a60c001518b61010001518c6080015161ffff168d602001518d611b69565b98508515610fd75787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d8060008114610f91576040519150601f19603f3d011682016040523d82523d6000602084013e610f96565b606091505b5050905080610fd1576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061100b565b61100b8a604001518a8c610100015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b8561101b5789610100015161101e565b60005b73ffffffffffffffffffffffffffffffffffffffff1687611043578a60e00151611046565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518d6040516110b5929190918252602082015260400190565b60405180910390a45050505050505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261119e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c22565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161111c565b50505050565b60007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1081611239610100850185612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061127b92505050610120860186612679565b9050905060008073ffffffffffffffffffffffffffffffffffffffff16836000815181106112ab576112ab6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168484815181106112f7576112f76126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115611387578454845173ffffffffffffffffffffffffffffffffffffffff90911690859060009061134c5761134c6126e1565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008161143f578484815181106113a0576113a06126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143a9190612710565b611441565b475b905060006114d061145560408b018b612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508c3591508990506114996101208e018e612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d3192505050565b90506114ef60208a01356114ea60a08c0160808d01612808565b611b42565b81600183516114fe9190612823565b8151811061150e5761150e6126e1565b6020026020010151101561154e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8581101561176f5760006115668260016127f5565b9050600088828151811061157c5761157c6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168984815181106115ac576115ac6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106115d65760006115d9565b60015b9050600060028a516115eb9190612823565b84106115f7573061162a565b6116056101208e018e612679565b84818110611615576116156126e1565b905060200201602081019061162a91906123a1565b905061163a6101208e018e612679565b8581811061164a5761164a6126e1565b905060200201602081019061165f91906123a1565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361169e57868581518110611691576116916126e1565b60200260200101516116a1565b60005b846116ad5760006116c8565b8786815181106116bf576116bf6126e1565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561174857600080fd5b505af115801561175c573d6000803e3d6000fd5b5050600190950194506115519350505050565b506000868681518110611784576117846126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190612710565b905082811080611836575061183389846127f5565b81105b1561186d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d66118816101008c0160e08d016123a1565b888881518110611893576118936126e1565b60200260200101518c60a00160208101906118ae9190612808565b61ffff168d60200135868b815181106118c9576118c96126e1565b6020026020010151611b69565b98508315611a125787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561194957600080fd5b505af115801561195d573d6000803e3d6000fd5b506000925061197591505060808c0160608d016123a1565b73ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146119cc576040519150601f19603f3d011682016040523d82523d6000602084013e6119d1565b606091505b5050905080611a0c576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611a65565b611a65611a2560808c0160608d016123a1565b8a898981518110611a3857611a386126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b83611a8957868681518110611a7c57611a7c6126e1565b6020026020010151611a8c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685611ac75787600081518110611aba57611aba6126e1565b6020026020010151611aca565b60005b73ffffffffffffffffffffffffffffffffffffffff16611af16101008d0160e08e016123a1565b604080518e358152602081018e905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f391016110b5565b6000612710611b518382612836565b611b5f9061ffff1685612858565b610310919061286f565b60006107d0841115611bb0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611bc2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611bf85760646032840204611bfb565b60005b9050808303838214611c1357611c138a8a8484611f66565b50505090910395945050505050565b6000611c84826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661202e9092919063ffffffff16565b9050805160001480611ca5575080806020019051810190611ca591906128aa565b61119e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611ba7565b805182516060919067ffffffffffffffff811115611d5157611d5161251b565b604051908082528060200260200182016040528015611d7a578160200160208202803683370190505b5091508482600081518110611d9157611d916126e1565b60200260200101818152505060005b81811015611f5c576000858281518110611dbc57611dbc6126e1565b60200260200101519050600086836001611dd691906127f5565b81518110611de657611de66126e1565b602002602001015190506000898481518110611e0457611e046126e1565b6020026020010151612710611e199190612836565b61ffff169050600080888681518110611e3457611e346126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115611f0557905b828b0282612710020181848d020281611f2057611f20612797565b049a508a88611f308860016127f5565b81518110611f4057611f406126e1565b6020908102919091010152505060019093019250611da0915050565b5050949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061203d8484600085612045565b949350505050565b6060824710156120d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611ba7565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161210091906128f7565b60006040518083038185875af1925050503d806000811461213d576040519150601f19603f3d011682016040523d82523d6000602084013e612142565b606091505b50915091506121538783838761215e565b979650505050505050565b606083156121f45782516000036121ed5773ffffffffffffffffffffffffffffffffffffffff85163b6121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611ba7565b508161203d565b61203d83838151156122095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79190612913565b6000610160828403121561225057600080fd5b50919050565b60006040828403121561225057600080fd5b600080610180838503121561227c57600080fd5b612286848461223d565b915061016083013567ffffffffffffffff8111156122a357600080fd5b6122af85828601612256565b9150509250929050565b600061016082840312156122cc57600080fd5b610310838361223d565b6000610140828403121561225057600080fd5b6000602082840312156122fb57600080fd5b813567ffffffffffffffff81111561231257600080fd5b61203d848285016122d6565b6000806040838503121561233157600080fd5b823567ffffffffffffffff8082111561234957600080fd5b612355868387016122d6565b9350602085013591508082111561236b57600080fd5b506122af85828601612256565b803573ffffffffffffffffffffffffffffffffffffffff8116811461239c57600080fd5b919050565b6000602082840312156123b357600080fd5b61031082612378565b803565ffffffffffff8116811461239c57600080fd5b6000602082840312156123e457600080fd5b610310826123bc565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261242257600080fd5b83018035915067ffffffffffffffff82111561243d57600080fd5b60200191503681900382131561245257600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715612595577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803561ffff8116811461239c57600080fd5b600061016082840312156125c057600080fd5b6125c861254a565b82358152602083013560208201526125e260408401612378565b60408201526125f360608401612378565b60608201526126046080840161259b565b608082015261261560a0840161259b565b60a082015261262660c08401612378565b60c082015261263760e08401612378565b60e082015261010061264a818501612378565b9082015261012061265c84820161259b565b9082015261014061266e8482016123bc565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126ae57600080fd5b83018035915067ffffffffffffffff8211156126c957600080fd5b6020019150600581901b360382131561245257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561272257600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461239c57600080fd5b60008060006060848603121561275c57600080fd5b61276584612729565b925061277360208501612729565b9150604084015163ffffffff8116811461278c57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610313576103136127c6565b60006020828403121561281a57600080fd5b6103108261259b565b81810381811115610313576103136127c6565b61ffff828116828216039080821115612851576128516127c6565b5092915050565b8082028115828204841417610313576103136127c6565b6000826128a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156128bc57600080fd5b815180151581146128cc57600080fd5b9392505050565b60005b838110156128ee5781810151838201526020016128d6565b50506000910152565b600082516129098184602087016128d3565b9190910192915050565b60208152600082518060208401526129328160408501602087016128d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de44c59485b64a44309171bd5ec5a3aa82d4e9417058be7ee66435ce87ad82ed64736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003f5760003560e01c806311f1fdef14610044578063baa8ed3514610076578063c83ee48414610089578063d1b72bc41461009c575b600080fd5b34801561005057600080fd5b5061006461005f366004612268565b6100bc565b60405190815260200160405180910390f35b6100646100843660046122b9565b610319565b6100646100973660046122e9565b61052d565b3480156100a857600080fd5b506100646100b736600461231e565b610766565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610126906101008c01908c016123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161015d6101608b016101408c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161018f61016089016101408a016123d2565b65ffffffffffff1690526101a660208701876123ed565b6040518563ffffffff1660e01b81526004016101c59493929190612459565b600060405180830381600087803b1580156101df57600080fd5b505af11580156101f3573d6000803e3d6000fd5b5050505061021e7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c785163361024e60808701606088016123a1565b8635610261610100890160e08a016123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102df57600080fd5b505af11580156102f3573d6000803e3d6000fd5b505050506103108380360381019061030b91906125ad565b610a0c565b90505b92915050565b600061032d610160830161014084016123d2565b65ffffffffffff1642111561036e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610381610100840160e085016123a1565b73ffffffffffffffffffffffffffffffffffffffff16036104d657348235146103d6576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561046257600080fd5b505af1158015610476573d6000803e3d6000fd5b50505050506104d182606001602081019061049191906123a1565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff169084356110ca565b61051b565b61051b336104ea60808501606086016123a1565b84356104fd610100870160e088016123a1565b73ffffffffffffffffffffffffffffffffffffffff169291906111a3565b61031361030b368490038401846125ad565b600061053f60e0830160c084016123d2565b65ffffffffffff16421115610580576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610590610100840184612679565b60008181106105a1576105a16126e1565b90506020020160208101906105b691906123a1565b73ffffffffffffffffffffffffffffffffffffffff16036106ef573482351461060b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561069757600080fd5b505af11580156106ab573d6000803e3d6000fd5b50505050506106ea828061012001906106c49190612679565b60008181106106d5576106d56126e1565b905060200201602081019061049191906123a1565b61075d565b61075d33610701610120850185612679565b6000818110610712576107126126e1565b905060200201602081019061072791906123a1565b8435610737610100870187612679565b6000818110610748576107486126e1565b90506020020160208101906104fd91906123a1565b61031382611207565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915260009173ffffffffffffffffffffffffffffffffffffffff1690632b67b5709033908060608101806107c96101008b018b612679565b60008181106107da576107da6126e1565b90506020020160208101906107ef91906123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161082460e08b0160c08c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161085460e0890160c08a016123d2565b65ffffffffffff16905261086b60208701876123ed565b6040518563ffffffff1660e01b815260040161088a9493929190612459565b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506108e37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633610911610120870187612679565b6000818110610922576109226126e1565b905060200201602081019061093791906123a1565b8635610947610100890189612679565b6000818110610958576109586126e1565b905060200201602081019061096d91906123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050505061031083611207565b60e08101516101008201516000917f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff918216159116158381610af8576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af39190612710565b610afa565b475b90508215610b2057835473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8115610b4557835473ffffffffffffffffffffffffffffffffffffffff166101008701525b600080876060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915087610100015173ffffffffffffffffffffffffffffffffffffffff168860e0015173ffffffffffffffffffffffffffffffffffffffff161115610c1f57905b610120880151885161ffff6127109283031691840290820290810190830281610c4a57610c4a612797565b04975050610c6088602001518960a00151611b42565b871015610c99576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1610610cde576000610ce1565b60015b9050886060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610d0e5789610d11565b60005b83610d1d576000610d1f565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015610d8957600080fd5b505af1158015610d9d573d6000803e3d6000fd5b505050506101008901516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190612710565b905084811080610e4f5750610e4c89866127f5565b81105b15610e86576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea88a60c001518b61010001518c6080015161ffff168d602001518d611b69565b98508515610fd75787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d8060008114610f91576040519150601f19603f3d011682016040523d82523d6000602084013e610f96565b606091505b5050905080610fd1576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061100b565b61100b8a604001518a8c610100015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b8561101b5789610100015161101e565b60005b73ffffffffffffffffffffffffffffffffffffffff1687611043578a60e00151611046565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518d6040516110b5929190918252602082015260400190565b60405180910390a45050505050505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261119e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c22565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161111c565b50505050565b60007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1081611239610100850185612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061127b92505050610120860186612679565b9050905060008073ffffffffffffffffffffffffffffffffffffffff16836000815181106112ab576112ab6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168484815181106112f7576112f76126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115611387578454845173ffffffffffffffffffffffffffffffffffffffff90911690859060009061134c5761134c6126e1565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008161143f578484815181106113a0576113a06126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143a9190612710565b611441565b475b905060006114d061145560408b018b612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508c3591508990506114996101208e018e612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d3192505050565b90506114ef60208a01356114ea60a08c0160808d01612808565b611b42565b81600183516114fe9190612823565b8151811061150e5761150e6126e1565b6020026020010151101561154e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8581101561176f5760006115668260016127f5565b9050600088828151811061157c5761157c6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168984815181106115ac576115ac6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106115d65760006115d9565b60015b9050600060028a516115eb9190612823565b84106115f7573061162a565b6116056101208e018e612679565b84818110611615576116156126e1565b905060200201602081019061162a91906123a1565b905061163a6101208e018e612679565b8581811061164a5761164a6126e1565b905060200201602081019061165f91906123a1565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361169e57868581518110611691576116916126e1565b60200260200101516116a1565b60005b846116ad5760006116c8565b8786815181106116bf576116bf6126e1565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561174857600080fd5b505af115801561175c573d6000803e3d6000fd5b5050600190950194506115519350505050565b506000868681518110611784576117846126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190612710565b905082811080611836575061183389846127f5565b81105b1561186d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d66118816101008c0160e08d016123a1565b888881518110611893576118936126e1565b60200260200101518c60a00160208101906118ae9190612808565b61ffff168d60200135868b815181106118c9576118c96126e1565b6020026020010151611b69565b98508315611a125787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561194957600080fd5b505af115801561195d573d6000803e3d6000fd5b506000925061197591505060808c0160608d016123a1565b73ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146119cc576040519150601f19603f3d011682016040523d82523d6000602084013e6119d1565b606091505b5050905080611a0c576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611a65565b611a65611a2560808c0160608d016123a1565b8a898981518110611a3857611a386126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b83611a8957868681518110611a7c57611a7c6126e1565b6020026020010151611a8c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685611ac75787600081518110611aba57611aba6126e1565b6020026020010151611aca565b60005b73ffffffffffffffffffffffffffffffffffffffff16611af16101008d0160e08e016123a1565b604080518e358152602081018e905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f391016110b5565b6000612710611b518382612836565b611b5f9061ffff1685612858565b610310919061286f565b60006107d0841115611bb0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611bc2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611bf85760646032840204611bfb565b60005b9050808303838214611c1357611c138a8a8484611f66565b50505090910395945050505050565b6000611c84826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661202e9092919063ffffffff16565b9050805160001480611ca5575080806020019051810190611ca591906128aa565b61119e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611ba7565b805182516060919067ffffffffffffffff811115611d5157611d5161251b565b604051908082528060200260200182016040528015611d7a578160200160208202803683370190505b5091508482600081518110611d9157611d916126e1565b60200260200101818152505060005b81811015611f5c576000858281518110611dbc57611dbc6126e1565b60200260200101519050600086836001611dd691906127f5565b81518110611de657611de66126e1565b602002602001015190506000898481518110611e0457611e046126e1565b6020026020010151612710611e199190612836565b61ffff169050600080888681518110611e3457611e346126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115611f0557905b828b0282612710020181848d020281611f2057611f20612797565b049a508a88611f308860016127f5565b81518110611f4057611f406126e1565b6020908102919091010152505060019093019250611da0915050565b5050949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061203d8484600085612045565b949350505050565b6060824710156120d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611ba7565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161210091906128f7565b60006040518083038185875af1925050503d806000811461213d576040519150601f19603f3d011682016040523d82523d6000602084013e612142565b606091505b50915091506121538783838761215e565b979650505050505050565b606083156121f45782516000036121ed5773ffffffffffffffffffffffffffffffffffffffff85163b6121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611ba7565b508161203d565b61203d83838151156122095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79190612913565b6000610160828403121561225057600080fd5b50919050565b60006040828403121561225057600080fd5b600080610180838503121561227c57600080fd5b612286848461223d565b915061016083013567ffffffffffffffff8111156122a357600080fd5b6122af85828601612256565b9150509250929050565b600061016082840312156122cc57600080fd5b610310838361223d565b6000610140828403121561225057600080fd5b6000602082840312156122fb57600080fd5b813567ffffffffffffffff81111561231257600080fd5b61203d848285016122d6565b6000806040838503121561233157600080fd5b823567ffffffffffffffff8082111561234957600080fd5b612355868387016122d6565b9350602085013591508082111561236b57600080fd5b506122af85828601612256565b803573ffffffffffffffffffffffffffffffffffffffff8116811461239c57600080fd5b919050565b6000602082840312156123b357600080fd5b61031082612378565b803565ffffffffffff8116811461239c57600080fd5b6000602082840312156123e457600080fd5b610310826123bc565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261242257600080fd5b83018035915067ffffffffffffffff82111561243d57600080fd5b60200191503681900382131561245257600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715612595577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803561ffff8116811461239c57600080fd5b600061016082840312156125c057600080fd5b6125c861254a565b82358152602083013560208201526125e260408401612378565b60408201526125f360608401612378565b60608201526126046080840161259b565b608082015261261560a0840161259b565b60a082015261262660c08401612378565b60c082015261263760e08401612378565b60e082015261010061264a818501612378565b9082015261012061265c84820161259b565b9082015261014061266e8482016123bc565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126ae57600080fd5b83018035915067ffffffffffffffff8211156126c957600080fd5b6020019150600581901b360382131561245257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561272257600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461239c57600080fd5b60008060006060848603121561275c57600080fd5b61276584612729565b925061277360208501612729565b9150604084015163ffffffff8116811461278c57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610313576103136127c6565b60006020828403121561281a57600080fd5b6103108261259b565b81810381811115610313576103136127c6565b61ffff828116828216039080821115612851576128516127c6565b5092915050565b8082028115828204841417610313576103136127c6565b6000826128a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156128bc57600080fd5b815180151581146128cc57600080fd5b9392505050565b60005b838110156128ee5781810151838201526020016128d6565b50506000910152565b600082516129098184602087016128d3565b9190910192915050565b60208152600082518060208401526129328160408501602087016128d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de44c59485b64a44309171bd5ec5a3aa82d4e9417058be7ee66435ce87ad82ed64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/UniV3Callback.json b/packages/hardhat/deployments/arbitrum/UniV3Callback.json index 462164fa..000bf28a 100644 --- a/packages/hardhat/deployments/arbitrum/UniV3Callback.json +++ b/packages/hardhat/deployments/arbitrum/UniV3Callback.json @@ -1,5 +1,5 @@ { - "address": "0x65F1F2Bf39c3d72a8801e67372147D3BFC997f41", + "address": "0x177dbf9D5C601B7A7a358aD752Ac1D7d54986D5a", "abi": [ { "inputs": [], @@ -122,28 +122,28 @@ "type": "function" } ], - "transactionHash": "0x4e91ddb07437248b24248a4ca3b89b0bedb674b8f9ae4992dced298d5eaac472", + "transactionHash": "0xe20fc6422621fe37cfe813918fe6312b89958027b59e263cc16d7350d729477a", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x65F1F2Bf39c3d72a8801e67372147D3BFC997f41", + "contractAddress": "0x177dbf9D5C601B7A7a358aD752Ac1D7d54986D5a", "transactionIndex": 1, - "gasUsed": "1781913", + "gasUsed": "5899095", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5b680bfa469abbdd95f81ef5c7f5ad4341eb5cbbea5a93b3bc7c249515ca3051", - "transactionHash": "0x4e91ddb07437248b24248a4ca3b89b0bedb674b8f9ae4992dced298d5eaac472", + "blockHash": "0x3dcab7cff1145d6a643d90c092c1a52c55815dfa17902f08e936fa491cbebb94", + "transactionHash": "0xe20fc6422621fe37cfe813918fe6312b89958027b59e263cc16d7350d729477a", "logs": [], - "blockNumber": 141614235, - "cumulativeGasUsed": "1781913", + "blockNumber": 147606445, + "cumulativeGasUsed": "5899095", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 8, - "solcInputHash": "4a9aead708515414ed961374f1d066ed", - "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\":\"pancakeV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"ramsesV2SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swapCallback\",\"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\"},\"pancakeV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"ramsesV2SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"swapCallback(int256,int256,bytes)\":{\"notice\":\"KyperSwap V2 callback 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 /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * KyperSwap V2 callback\\n * NOTE: None of these arguments can be trusted\\n */\\n function swapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x85ecd0df604a102bbc22cbcfd07afec90fd4abb25b8fac2ce0bda48ba5663f82\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107f7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610687565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d5490911692820192909252903090036101c057805160408201516101bb9173ffffffffffffffffffffffffffffffffffffffff9091169033906102d2565b610288565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561026f57600080fd5b505af1158015610283573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261035f908490610364565b505050565b60006103c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104789092919063ffffffff16565b90508051600014806103e75750808060200190518101906103e79190610707565b61035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610487848460008561048f565b949350505050565b606082471015610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046f565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161054a9190610754565b60006040518083038185875af1925050503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d878383876105a8565b979650505050505050565b6060831561063e5782516000036106375773ffffffffffffffffffffffffffffffffffffffff85163b610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046f565b5081610487565b61048783838151156106535781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046f9190610770565b6000806000806060858703121561069d57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156106c357600080fd5b818701915087601f8301126106d757600080fd5b8135818111156106e657600080fd5b8860208285010111156106f857600080fd5b95989497505060200194505050565b60006020828403121561071957600080fd5b8151801515811461072957600080fd5b9392505050565b60005b8381101561074b578181015183820152602001610733565b50506000910152565b60008251610766818460208701610730565b9190910192915050565b602081526000825180602084015261078f816040850160208701610730565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e0c3a5ea77a59d4a136519a3fb790277ee65b84323dca008c9268c0208c1cb4364736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610687565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d5490911692820192909252903090036101c057805160408201516101bb9173ffffffffffffffffffffffffffffffffffffffff9091169033906102d2565b610288565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561026f57600080fd5b505af1158015610283573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261035f908490610364565b505050565b60006103c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104789092919063ffffffff16565b90508051600014806103e75750808060200190518101906103e79190610707565b61035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610487848460008561048f565b949350505050565b606082471015610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046f565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161054a9190610754565b60006040518083038185875af1925050503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d878383876105a8565b979650505050505050565b6060831561063e5782516000036106375773ffffffffffffffffffffffffffffffffffffffff85163b610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046f565b5081610487565b61048783838151156106535781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046f9190610770565b6000806000806060858703121561069d57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156106c357600080fd5b818701915087601f8301126106d757600080fd5b8135818111156106e657600080fd5b8860208285010111156106f857600080fd5b95989497505060200194505050565b60006020828403121561071957600080fd5b8151801515811461072957600080fd5b9392505050565b60005b8381101561074b578181015183820152602001610733565b50506000910152565b60008251610766818460208701610730565b9190910192915050565b602081526000825180602084015261078f816040850160208701610730565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e0c3a5ea77a59d4a136519a3fb790277ee65b84323dca008c9268c0208c1cb4364736f6c63430008130033", + "numDeployments": 9, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "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\":\"pancakeV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"ramsesV2SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swapCallback\",\"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\"},\"pancakeV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"ramsesV2SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"swapCallback(int256,int256,bytes)\":{\"notice\":\"KyperSwap V2 callback 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 if (callback.usePermit == 1) {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n } else {\\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\\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 /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * KyperSwap V2 callback\\n * NOTE: None of these arguments can be trusted\\n */\\n function swapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xe3eb6dae32a233cc02e3aa833b2a7bac774a3c9c2c11f6d8feae8745d976f4b6\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610903806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610793565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e546060820152903090036101e757805160408201516101e29173ffffffffffffffffffffffffffffffffffffffff909116903390610339565b6102ef565b80606001516001036102bf577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156102a257600080fd5b505af11580156102b6573d6000803e3d6000fd5b505050506102ef565b6020810151815160408301516102ef9273ffffffffffffffffffffffffffffffffffffffff909116913390610412565b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261040d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610470565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526100899085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161038b565b60006104d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166105849092919063ffffffff16565b90508051600014806104f35750808060200190518101906104f39190610813565b61040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610593848460008561059b565b949350505050565b60608247101561062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161057b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106569190610860565b60006040518083038185875af1925050503d8060008114610693576040519150601f19603f3d011682016040523d82523d6000602084013e610698565b606091505b50915091506106a9878383876106b4565b979650505050505050565b6060831561074a5782516000036107435773ffffffffffffffffffffffffffffffffffffffff85163b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057b565b5081610593565b610593838381511561075f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b919061087c565b600080600080606085870312156107a957600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156107cf57600080fd5b818701915087601f8301126107e357600080fd5b8135818111156107f257600080fd5b88602082850101111561080457600080fd5b95989497505060200194505050565b60006020828403121561082557600080fd5b8151801515811461083557600080fd5b9392505050565b60005b8381101561085757818101518382015260200161083f565b50506000910152565b6000825161087281846020870161083c565b9190910192915050565b602081526000825180602084015261089b81604085016020870161083c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bd61054b7d7be6361f4cde7d339ff2b4e90fc18022d2e43caaa86ef48c70f7df64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610793565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e546060820152903090036101e757805160408201516101e29173ffffffffffffffffffffffffffffffffffffffff909116903390610339565b6102ef565b80606001516001036102bf577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156102a257600080fd5b505af11580156102b6573d6000803e3d6000fd5b505050506102ef565b6020810151815160408301516102ef9273ffffffffffffffffffffffffffffffffffffffff909116913390610412565b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261040d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610470565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526100899085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161038b565b60006104d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166105849092919063ffffffff16565b90508051600014806104f35750808060200190518101906104f39190610813565b61040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610593848460008561059b565b949350505050565b60608247101561062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161057b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106569190610860565b60006040518083038185875af1925050503d8060008114610693576040519150601f19603f3d011682016040523d82523d6000602084013e610698565b606091505b50915091506106a9878383876106b4565b979650505050505050565b6060831561074a5782516000036107435773ffffffffffffffffffffffffffffffffffffffff85163b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057b565b5081610593565b610593838381511561075f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b919061087c565b600080600080606085870312156107a957600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156107cf57600080fd5b818701915087601f8301126107e357600080fd5b8135818111156107f257600080fd5b88602082850101111561080457600080fd5b95989497505060200194505050565b60006020828403121561082557600080fd5b8151801515811461083557600080fd5b9392505050565b60005b8381101561085757818101518382015260200161083f565b50506000910152565b6000825161087281846020870161083c565b9190910192915050565b602081526000825180602084015261089b81604085016020870161083c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bd61054b7d7be6361f4cde7d339ff2b4e90fc18022d2e43caaa86ef48c70f7df64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/UniV3Like.json b/packages/hardhat/deployments/arbitrum/UniV3Like.json index 571366b5..900ef68a 100644 --- a/packages/hardhat/deployments/arbitrum/UniV3Like.json +++ b/packages/hardhat/deployments/arbitrum/UniV3Like.json @@ -1,5 +1,5 @@ { - "address": "0xF580602dd830057B82Bc63C7dcbB04C7d1697115", + "address": "0x4c5c96f8E68b47DCc41E4c253A4ED9147b5ADc26", "abi": [ { "inputs": [], @@ -136,6 +136,72 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV3LikeExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -208,7 +274,78 @@ "type": "tuple" } ], - "name": "uniswapV3LikeExactInput", + "name": "uniswapV3LikeExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV3LikeExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -296,7 +433,7 @@ "type": "tuple" } ], - "name": "uniswapV3LikeExactInputSingle", + "name": "uniswapV3LikeExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -304,32 +441,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0x1beeda45bb7f1a1b94b65f9050b7d4752c2db7d0f2422748bef0fcf0fe76974d", + "transactionHash": "0xe80f86e9ce3396a7e322010e9c330b5d4aaf62878c6b395f35656f17b7989fe5", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xF580602dd830057B82Bc63C7dcbB04C7d1697115", - "transactionIndex": 2, - "gasUsed": "5737321", + "contractAddress": "0x4c5c96f8E68b47DCc41E4c253A4ED9147b5ADc26", + "transactionIndex": 1, + "gasUsed": "16641894", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x058cd0300cab58034b2309b1d9b30f887858ebc90cbd8c5d692d1a0f2a8fe103", - "transactionHash": "0x1beeda45bb7f1a1b94b65f9050b7d4752c2db7d0f2422748bef0fcf0fe76974d", + "blockHash": "0xa6c73c507a417f10e42d9f400cbb8a6738e8c7661a499d35f23a92ad0cd8a65d", + "transactionHash": "0xe80f86e9ce3396a7e322010e9c330b5d4aaf62878c6b395f35656f17b7989fe5", "logs": [], - "blockNumber": 141960362, - "cumulativeGasUsed": "5958167", + "blockNumber": 147606499, + "cumulativeGasUsed": "16641894", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 10, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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/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 {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokens[0],\\n isToEth ? address(0) : params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0778264b402de681401a9d1ca9ee9e1d313e2075b7d853b1504704a605ba6c23\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\\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\":\"0x61677478daa5f86ad18959bbe4a13b95a997853f844642be3f6eb54d6ab9a772\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612421806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611de2565b610066565b60405190815260200160405180910390f35b610041610061366004611f8f565b6109f6565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029291906120a9565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff1681525089806020019061045191906120c2565b6040518563ffffffff1660e01b8152600401610470949392919061212e565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e91906121f0565b9150508061057b90612243565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906121f0565b50905061066381612243565b9550505b61066f61173b565b610682876101000151886060015161179b565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906120a9565b9050828110806107685750610765868461227b565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c188602001518960e001518a6040015161ffff168b61010001518a6117cb565b95508315610910577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108ca576040519150601f19603f3d011682016040523d82523d6000602084013e6108cf565b606091505b505090508061090a576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061093a565b875160e089015161093a9173ffffffffffffffffffffffffffffffffffffffff9091169088611884565b83610949578760e0015161094c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685610971578860c00151610974565b60005b73ffffffffffffffffffffffffffffffffffffffff16896020015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38b608001518a6040516109e3929190918252602082015260400190565b60405180910390a4505050505092915050565b60008260a0015165ffffffffffff16421115610a3e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e0840151805160009182918290610a5f57610a5f61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e001518481518110610aaf57610aaf61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610add5733610adf565b305b90508215610bfd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610b3b57610b3b61228e565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610b9a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b5050505050505b8115610c90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610c5557610c5561228e565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610ca857610ca861228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906120a9565b88519650905083610ed3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610ddb57610ddb61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610e8191906120c2565b6040518563ffffffff1660e01b8152600401610ea0949392919061212e565b600060405180830381600087803b158015610eba57600080fd5b505af1158015610ece573d6000803e3d6000fd5b505050505b60005b858110156111c457600081600101905060008a60e001518281518110610efe57610efe61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610f3257610f3261228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610fbf60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610f9957610f9961228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b80156110b65760008b61010001518481518110610fde57610fde61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a191906121f0565b915050806110ae90612243565b9950506111b1565b60008b610100015184815181106110cf576110cf61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906121f0565b5090506111ad81612243565b9950505b6111b961173b565b503093509050610ed6565b506111d386896060015161179b565b86101561120c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e0015186815181106112245761122461228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561129a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112be91906120a9565b9050818110806112d657506112d3878361227b565b81105b1561130d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113478960c001518a60e00151888151811061132b5761132b61228e565b60200260200101518b6080015161ffff168c602001518b6117cb565b96508315611496577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156113da57600080fd5b505af11580156113ee573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611450576040519150601f19603f3d011682016040523d82523d6000602084013e611455565b606091505b5050905080611490576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506114e2565b6114e28960400151888b60e0015189815181106114b5576114b561228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166118849092919063ffffffff16565b8361150a578860e0015186815181106114fd576114fd61228e565b602002602001015161150d565b60005b73ffffffffffffffffffffffffffffffffffffffff168561154c578960e0015160008151811061153f5761153f61228e565b602002602001015161154f565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b6040516115be929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611630576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611799576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60006127106117aa83826122bd565b6117b89061ffff16856122df565b6117c291906122f6565b90505b92915050565b60006107d0841115611812576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611824575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561185a576064603284020461185d565b60005b9050808303838214611875576118758a8a8484611916565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526119119084906119de565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611a40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611aed9092919063ffffffff16565b9050805160001480611a61575080806020019051810190611a619190612331565b611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611809565b6060611afc8484600085611b04565b949350505050565b606082471015611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611809565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbf919061237e565b60006040518083038185875af1925050503d8060008114611bfc576040519150601f19603f3d011682016040523d82523d6000602084013e611c01565b606091505b5091509150611c1287838387611c1d565b979650505050505050565b60608315611cb3578251600003611cac5773ffffffffffffffffffffffffffffffffffffffff85163b611cac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611809565b5081611afc565b611afc8383815115611cc85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611809919061239a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b60405290565b604051610120810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d9d57600080fd5b919050565b803561ffff81168114611d9d57600080fd5b803565ffffffffffff81168114611d9d57600080fd5b600060408284031215611ddc57600080fd5b50919050565b600080828403610160811215611df757600080fd5b61014080821215611e0757600080fd5b611e0f611d2b565b9150611e1a85611d79565b8252611e2860208601611d79565b6020830152611e3960408601611da2565b6040830152611e4a60608601611da2565b606083015260808501356080830152611e6560a08601611db4565b60a0830152611e7660c08601611d79565b60c0830152611e8760e08601611d79565b60e08301526101008581013590830152610120611ea5818701611d79565b9083015290925083013567ffffffffffffffff811115611ec457600080fd5b611ed085828601611dca565b9150509250929050565b600082601f830112611eeb57600080fd5b8135602067ffffffffffffffff80831115611f0857611f08611cfc565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611f4b57611f4b611cfc565b604052938452858101830193838101925087851115611f6957600080fd5b83870191505b84821015611c1257611f8082611d79565b83529183019190830190611f6f565b60008060408385031215611fa257600080fd5b823567ffffffffffffffff80821115611fba57600080fd5b908401906101208287031215611fcf57600080fd5b611fd7611d55565b8235815260208301356020820152611ff160408401611d79565b604082015261200260608401611da2565b606082015261201360808401611da2565b608082015261202460a08401611db4565b60a082015261203560c08401611d79565b60c082015260e08301358281111561204c57600080fd5b61205888828601611eda565b60e083015250610100808401358381111561207257600080fd5b61207e89828701611eda565b82840152505080945050602085013591508082111561209c57600080fd5b50611ed085828601611dca565b6000602082840312156120bb57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120f757600080fd5b83018035915067ffffffffffffffff82111561211257600080fd5b60200191503681900382131561212757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561220357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361227457612274612214565b5060000390565b808201808211156117c5576117c5612214565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156122d8576122d8612214565b5092915050565b80820281158282048414176117c5576117c5612214565b60008261232c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561234357600080fd5b8151801515811461235357600080fd5b9392505050565b60005b8381101561237557818101518382015260200161235d565b50506000910152565b6000825161239081846020870161235a565b9190910192915050565b60208152600082518060208401526123b981604085016020870161235a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220576050a04e57b56eff16cf6c316bc8966ab4a176dcea2edf74c13dd26adc111164736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611de2565b610066565b60405190815260200160405180910390f35b610041610061366004611f8f565b6109f6565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029291906120a9565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff1681525089806020019061045191906120c2565b6040518563ffffffff1660e01b8152600401610470949392919061212e565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e91906121f0565b9150508061057b90612243565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906121f0565b50905061066381612243565b9550505b61066f61173b565b610682876101000151886060015161179b565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906120a9565b9050828110806107685750610765868461227b565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c188602001518960e001518a6040015161ffff168b61010001518a6117cb565b95508315610910577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108ca576040519150601f19603f3d011682016040523d82523d6000602084013e6108cf565b606091505b505090508061090a576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061093a565b875160e089015161093a9173ffffffffffffffffffffffffffffffffffffffff9091169088611884565b83610949578760e0015161094c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685610971578860c00151610974565b60005b73ffffffffffffffffffffffffffffffffffffffff16896020015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38b608001518a6040516109e3929190918252602082015260400190565b60405180910390a4505050505092915050565b60008260a0015165ffffffffffff16421115610a3e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e0840151805160009182918290610a5f57610a5f61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e001518481518110610aaf57610aaf61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610add5733610adf565b305b90508215610bfd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610b3b57610b3b61228e565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610b9a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b5050505050505b8115610c90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610c5557610c5561228e565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610ca857610ca861228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906120a9565b88519650905083610ed3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610ddb57610ddb61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610e8191906120c2565b6040518563ffffffff1660e01b8152600401610ea0949392919061212e565b600060405180830381600087803b158015610eba57600080fd5b505af1158015610ece573d6000803e3d6000fd5b505050505b60005b858110156111c457600081600101905060008a60e001518281518110610efe57610efe61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610f3257610f3261228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610fbf60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610f9957610f9961228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b80156110b65760008b61010001518481518110610fde57610fde61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a191906121f0565b915050806110ae90612243565b9950506111b1565b60008b610100015184815181106110cf576110cf61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906121f0565b5090506111ad81612243565b9950505b6111b961173b565b503093509050610ed6565b506111d386896060015161179b565b86101561120c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e0015186815181106112245761122461228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561129a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112be91906120a9565b9050818110806112d657506112d3878361227b565b81105b1561130d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113478960c001518a60e00151888151811061132b5761132b61228e565b60200260200101518b6080015161ffff168c602001518b6117cb565b96508315611496577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156113da57600080fd5b505af11580156113ee573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611450576040519150601f19603f3d011682016040523d82523d6000602084013e611455565b606091505b5050905080611490576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506114e2565b6114e28960400151888b60e0015189815181106114b5576114b561228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166118849092919063ffffffff16565b8361150a578860e0015186815181106114fd576114fd61228e565b602002602001015161150d565b60005b73ffffffffffffffffffffffffffffffffffffffff168561154c578960e0015160008151811061153f5761153f61228e565b602002602001015161154f565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b6040516115be929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611630576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611799576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60006127106117aa83826122bd565b6117b89061ffff16856122df565b6117c291906122f6565b90505b92915050565b60006107d0841115611812576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611824575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561185a576064603284020461185d565b60005b9050808303838214611875576118758a8a8484611916565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526119119084906119de565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611a40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611aed9092919063ffffffff16565b9050805160001480611a61575080806020019051810190611a619190612331565b611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611809565b6060611afc8484600085611b04565b949350505050565b606082471015611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611809565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbf919061237e565b60006040518083038185875af1925050503d8060008114611bfc576040519150601f19603f3d011682016040523d82523d6000602084013e611c01565b606091505b5091509150611c1287838387611c1d565b979650505050505050565b60608315611cb3578251600003611cac5773ffffffffffffffffffffffffffffffffffffffff85163b611cac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611809565b5081611afc565b611afc8383815115611cc85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611809919061239a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b60405290565b604051610120810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d9d57600080fd5b919050565b803561ffff81168114611d9d57600080fd5b803565ffffffffffff81168114611d9d57600080fd5b600060408284031215611ddc57600080fd5b50919050565b600080828403610160811215611df757600080fd5b61014080821215611e0757600080fd5b611e0f611d2b565b9150611e1a85611d79565b8252611e2860208601611d79565b6020830152611e3960408601611da2565b6040830152611e4a60608601611da2565b606083015260808501356080830152611e6560a08601611db4565b60a0830152611e7660c08601611d79565b60c0830152611e8760e08601611d79565b60e08301526101008581013590830152610120611ea5818701611d79565b9083015290925083013567ffffffffffffffff811115611ec457600080fd5b611ed085828601611dca565b9150509250929050565b600082601f830112611eeb57600080fd5b8135602067ffffffffffffffff80831115611f0857611f08611cfc565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611f4b57611f4b611cfc565b604052938452858101830193838101925087851115611f6957600080fd5b83870191505b84821015611c1257611f8082611d79565b83529183019190830190611f6f565b60008060408385031215611fa257600080fd5b823567ffffffffffffffff80821115611fba57600080fd5b908401906101208287031215611fcf57600080fd5b611fd7611d55565b8235815260208301356020820152611ff160408401611d79565b604082015261200260608401611da2565b606082015261201360808401611da2565b608082015261202460a08401611db4565b60a082015261203560c08401611d79565b60c082015260e08301358281111561204c57600080fd5b61205888828601611eda565b60e083015250610100808401358381111561207257600080fd5b61207e89828701611eda565b82840152505080945050602085013591508082111561209c57600080fd5b50611ed085828601611dca565b6000602082840312156120bb57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120f757600080fd5b83018035915067ffffffffffffffff82111561211257600080fd5b60200191503681900382131561212757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561220357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361227457612274612214565b5060000390565b808201808211156117c5576117c5612214565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156122d8576122d8612214565b5092915050565b80820281158282048414176117c5576117c5612214565b60008261232c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561234357600080fd5b8151801515811461235357600080fd5b9392505050565b60005b8381101561237557818101518382015260200161235d565b50506000910152565b6000825161239081846020870161235a565b9190910192915050565b60208152600082518060208401526123b981604085016020870161235a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220576050a04e57b56eff16cf6c316bc8966ab4a176dcea2edf74c13dd26adc111164736f6c63430008130033", + "numDeployments": 11, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"name\":\"uniswapV3LikeExactInput\",\"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\":\"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\":\"uniswapV3LikeExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"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\":\"uniswapV3LikeExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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/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 {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\\n ExactInputSingleParams calldata params,\\n uint256 usePermit\\n ) internal returns (uint256 amountOut) {\\n bool isFromEth = params.tokenIn == address(0);\\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\\n\\n address tokenOut = params.tokenOut == address(0)\\n ? address(LibWarp.state().weth)\\n : params.tokenOut;\\n\\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = tokenIn < tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: tokenIn,\\n amount: params.amountIn,\\n usePermit: usePermit\\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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (params.tokenOut == address(0)) {\\n // To ETH, unwrap WETH\\n // TODO: This is read twice. Compare gas usage\\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(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn == address(0)) {\\n // From ETH, wrap it\\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\\n }\\n\\n function uniswapV3LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\\n }\\n\\n function uniswapV3LikeExactInputInternal(\\n ExactInputParams calldata params,\\n uint256 usePermit\\n ) internal returns (uint256 amountOut) {\\n uint256 poolLength = params.pools.length;\\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\\n address[] memory tokens = params.tokens;\\n\\n if (params.tokens[0] == address(0)) {\\n tokens[0] = address(LibWarp.state().weth);\\n }\\n\\n if (params.tokens[poolLength] == address(0)) {\\n tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: payer,\\n token: tokens[index],\\n amount: amountOut,\\n usePermit: usePermit\\n })\\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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (params.tokens[poolLength] == address(0)) {\\n // To ETH, unwrap\\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n params.tokens[0],\\n params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokens[0] == address(0)) {\\n // From ETH, wrap it\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n }\\n\\n return uniswapV3LikeExactInputInternal(params, 0);\\n }\\n\\n function uniswapV3LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 return uniswapV3LikeExactInputInternal(params, 1);\\n }\\n}\\n\",\"keccak256\":\"0x9e23653ffdee1ddba14b812d0ed30da1b28d009e139fef4562407e722f5c541f\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\\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 calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x1fbea0694f83750cccdc1e2e316bc7466e7d04e7342fd7d4359459f056d30a71\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506125e1806100206000396000f3fe60806040526004361061003e5760003560e01c80626ee8b6146100435780635576abd114610068578063a33aea141461007b578063cda932d11461009b575b600080fd5b610056610051366004612064565b6100bb565b60405190815260200160405180910390f35b6100566100763660046120ac565b61024f565b34801561008757600080fd5b506100566100963660046120db565b6103b2565b3480156100a757600080fd5b506100566100b636600461212c565b6104fc565b60006100cd60c0830160a08401612186565b65ffffffffffff1642111561010e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061011d60e08401846121ae565b600081811061012e5761012e61221d565b9050602002016020810190610143919061224c565b73ffffffffffffffffffffffffffffffffffffffff160361023e5734823514610198576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b50505050505b61024982600061065b565b92915050565b600061026160c0830160a08401612186565b65ffffffffffff164211156102a2576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b460e0840160c0850161224c565b73ffffffffffffffffffffffffffffffffffffffff16036103a7577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660808301353414610344576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561038c57600080fd5b505af11580156103a0573d6000803e3d6000fd5b5050505050505b610249826000611118565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b57091339181906060820190819061041a908b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff908116825260808b013516602082015260400161045260c08b0160a08c01612186565b65ffffffffffff9081168252893516602091820152908252309082015260400161048260c0890160a08a01612186565b65ffffffffffff1690526104996020870187612282565b6040518563ffffffff1660e01b81526004016104b894939291906122e7565b600060405180830381600087803b1580156104d257600080fd5b505af11580156104e6573d6000803e3d6000fd5b505050506104f5836001611118565b9392505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610561908b018b6121ae565b60008181106105725761057261221d565b9050602002016020810190610587919061224c565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016105bc60c08b0160a08c01612186565b65ffffffffffff908116825289351660209182015290825230908201526040016105ec60c0890160a08a01612186565b65ffffffffffff1690526106036020870187612282565b6040518563ffffffff1660e01b815260040161062294939291906122e7565b600060405180830381600087803b15801561063c57600080fd5b505af1158015610650573d6000803e3d6000fd5b505050506104f58360015b60008061066c6101008501856121ae565b9150600090508061068060e08701876121ae565b60008181106106915761069161221d565b90506020020160208101906106a6919061224c565b73ffffffffffffffffffffffffffffffffffffffff16146106c757336106c9565b305b905060006106da60e08701876121ae565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061071b9250505060e08801886121ae565b600081811061072c5761072c61221d565b9050602002016020810190610741919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036107e5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff9091169082906000906107aa576107aa61221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f460e08801886121ae565b858181106108045761080461221d565b9050602002016020810190610819919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036108be577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff909116908290859081106108835761088361221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008184815181106108d2576108d261221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c91906123a9565b87359550905060005b84811015610c8157600081600101905060008482815181106109995761099961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168584815181106109c9576109c961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610a5860405180608001604052808a81526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878681518110610a2c57610a2c61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018b815250611904565b8015610b61576000610a6e6101008c018c6121ae565b85818110610a7e57610a7e61221d565b9050602002016020810190610a93919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c91906123c2565b91505080610b5990612415565b985050610c6e565b6000610b716101008c018c6121ae565b85818110610b8157610b8161221d565b9050602002016020810190610b96919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5e91906123c2565b509050610c6a81612415565b9850505b610c76611a93565b503094509050610975565b50610c9b85610c9660808a0160608b0161244d565b611af3565b851015610cd4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828581518110610ce857610ce861221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8291906123a9565b905081811080610d9a5750610d978683612471565b81105b15610dd1576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e20610de460e08a0160c08b0161224c565b848781518110610df657610df661221d565b60200260200101518a6080016020810190610e11919061244d565b61ffff168b602001358a611b1a565b95506000610e3160e08a018a6121ae565b87818110610e4157610e4161221d565b9050602002016020810190610e56919061224c565b73ffffffffffffffffffffffffffffffffffffffff1603610fc5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b5060009250610f2891505060608a0160408b0161224c565b73ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610f7f576040519150601f19603f3d011682016040523d82523d6000602084013e610f84565b606091505b5050905080610fbf576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611018565b611018610fd860608a0160408b0161224c565b87858881518110610feb57610feb61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611bd39092919063ffffffff16565b61102560e08901896121ae565b868181106110355761103561221d565b905060200201602081019061104a919061224c565b73ffffffffffffffffffffffffffffffffffffffff1661106d60e08a018a6121ae565b600081811061107e5761107e61221d565b9050602002016020810190611093919061224c565b73ffffffffffffffffffffffffffffffffffffffff166110b960e08b0160c08c0161224c565b604080518c358152602081018b905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050505092915050565b6000808061112c60e0860160c0870161224c565b73ffffffffffffffffffffffffffffffffffffffff161490506000816111615761115c60e0860160c0870161224c565b61119a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b90506000806111b0610100880160e0890161224c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576111dc610100870160e0880161224c565b61121a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae91906123a9565b905060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610905061134860405180608001604052808a608001358152602001876113065733611308565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200189815250611904565b80156114335760006113626101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b013560448201526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e91906123c2565b9150508061142b90612415565b965050611522565b60006114476101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b0135604482015273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151291906123c2565b50905061151e81612415565b9650505b61152a611a93565b611543610100890135610c9660808b0160608c0161244d565b86101561157c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d91906123a9565b90508281108061162557506116228784612471565b81105b1561165c576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61169061166f60408b0160208c0161224c565b8561168060608d0160408e0161244d565b61ffff168c61010001358b611b1a565b965060006116a56101008b0160e08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1603611811577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d80600081146117cb576040519150601f19603f3d011682016040523d82523d6000602084013e6117d0565b606091505b505090508061180b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061183f565b61183f61182160208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff86169089611bd3565b6118506101008a0160e08b0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661187660e08b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661189c60408c0160208d0161224c565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c608001358b6040516118f0929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611962576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611af1576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612710611b028382612484565b611b109061ffff16856124a6565b6104f591906124bd565b60006107d0841115611b61576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611b73575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611ba95760646032840204611bac565b60005b9050808303838214611bc457611bc48a8a8484611c65565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611c60908490611d2d565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611d8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e3c9092919063ffffffff16565b9050805160001480611db0575080806020019051810190611db091906124f8565b611c60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611b58565b6060611e4b8484600085611e53565b949350505050565b606082471015611ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611b58565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611f0e919061253e565b60006040518083038185875af1925050503d8060008114611f4b576040519150601f19603f3d011682016040523d82523d6000602084013e611f50565b606091505b5091509150611f6187838387611f6c565b979650505050505050565b60608315612002578251600003611ffb5773ffffffffffffffffffffffffffffffffffffffff85163b611ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611b58565b5081611e4b565b611e4b83838151156120175781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b58919061255a565b6000610120828403121561205e57600080fd5b50919050565b60006020828403121561207657600080fd5b813567ffffffffffffffff81111561208d57600080fd5b611e4b8482850161204b565b6000610140828403121561205e57600080fd5b600061014082840312156120bf57600080fd5b6104f58383612099565b60006040828403121561205e57600080fd5b60008061016083850312156120ef57600080fd5b6120f98484612099565b915061014083013567ffffffffffffffff81111561211657600080fd5b612122858286016120c9565b9150509250929050565b6000806040838503121561213f57600080fd5b823567ffffffffffffffff8082111561215757600080fd5b6121638683870161204b565b9350602085013591508082111561217957600080fd5b50612122858286016120c9565b60006020828403121561219857600080fd5b813565ffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126121e357600080fd5b83018035915067ffffffffffffffff8211156121fe57600080fd5b6020019150600581901b360382131561221657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561225e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122b757600080fd5b83018035915067ffffffffffffffff8211156122d257600080fd5b60200191503681900382131561221657600080fd5b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156123bb57600080fd5b5051919050565b600080604083850312156123d557600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203612446576124466123e6565b5060000390565b60006020828403121561245f57600080fd5b813561ffff811681146104f557600080fd5b80820180821115610249576102496123e6565b61ffff82811682821603908082111561249f5761249f6123e6565b5092915050565b8082028115828204841417610249576102496123e6565b6000826124f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561250a57600080fd5b815180151581146104f557600080fd5b60005b8381101561253557818101518382015260200161251d565b50506000910152565b6000825161255081846020870161251a565b9190910192915050565b602081526000825180602084015261257981604085016020870161251a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122020ef15a82dfe9e15884ad78a08e0e295c6c50a821511c6e99799a1a517eefc3564736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003e5760003560e01c80626ee8b6146100435780635576abd114610068578063a33aea141461007b578063cda932d11461009b575b600080fd5b610056610051366004612064565b6100bb565b60405190815260200160405180910390f35b6100566100763660046120ac565b61024f565b34801561008757600080fd5b506100566100963660046120db565b6103b2565b3480156100a757600080fd5b506100566100b636600461212c565b6104fc565b60006100cd60c0830160a08401612186565b65ffffffffffff1642111561010e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061011d60e08401846121ae565b600081811061012e5761012e61221d565b9050602002016020810190610143919061224c565b73ffffffffffffffffffffffffffffffffffffffff160361023e5734823514610198576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b50505050505b61024982600061065b565b92915050565b600061026160c0830160a08401612186565b65ffffffffffff164211156102a2576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b460e0840160c0850161224c565b73ffffffffffffffffffffffffffffffffffffffff16036103a7577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660808301353414610344576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561038c57600080fd5b505af11580156103a0573d6000803e3d6000fd5b5050505050505b610249826000611118565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b57091339181906060820190819061041a908b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff908116825260808b013516602082015260400161045260c08b0160a08c01612186565b65ffffffffffff9081168252893516602091820152908252309082015260400161048260c0890160a08a01612186565b65ffffffffffff1690526104996020870187612282565b6040518563ffffffff1660e01b81526004016104b894939291906122e7565b600060405180830381600087803b1580156104d257600080fd5b505af11580156104e6573d6000803e3d6000fd5b505050506104f5836001611118565b9392505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610561908b018b6121ae565b60008181106105725761057261221d565b9050602002016020810190610587919061224c565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016105bc60c08b0160a08c01612186565b65ffffffffffff908116825289351660209182015290825230908201526040016105ec60c0890160a08a01612186565b65ffffffffffff1690526106036020870187612282565b6040518563ffffffff1660e01b815260040161062294939291906122e7565b600060405180830381600087803b15801561063c57600080fd5b505af1158015610650573d6000803e3d6000fd5b505050506104f58360015b60008061066c6101008501856121ae565b9150600090508061068060e08701876121ae565b60008181106106915761069161221d565b90506020020160208101906106a6919061224c565b73ffffffffffffffffffffffffffffffffffffffff16146106c757336106c9565b305b905060006106da60e08701876121ae565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061071b9250505060e08801886121ae565b600081811061072c5761072c61221d565b9050602002016020810190610741919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036107e5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff9091169082906000906107aa576107aa61221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f460e08801886121ae565b858181106108045761080461221d565b9050602002016020810190610819919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036108be577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff909116908290859081106108835761088361221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008184815181106108d2576108d261221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c91906123a9565b87359550905060005b84811015610c8157600081600101905060008482815181106109995761099961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168584815181106109c9576109c961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610a5860405180608001604052808a81526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878681518110610a2c57610a2c61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018b815250611904565b8015610b61576000610a6e6101008c018c6121ae565b85818110610a7e57610a7e61221d565b9050602002016020810190610a93919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c91906123c2565b91505080610b5990612415565b985050610c6e565b6000610b716101008c018c6121ae565b85818110610b8157610b8161221d565b9050602002016020810190610b96919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5e91906123c2565b509050610c6a81612415565b9850505b610c76611a93565b503094509050610975565b50610c9b85610c9660808a0160608b0161244d565b611af3565b851015610cd4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828581518110610ce857610ce861221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8291906123a9565b905081811080610d9a5750610d978683612471565b81105b15610dd1576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e20610de460e08a0160c08b0161224c565b848781518110610df657610df661221d565b60200260200101518a6080016020810190610e11919061244d565b61ffff168b602001358a611b1a565b95506000610e3160e08a018a6121ae565b87818110610e4157610e4161221d565b9050602002016020810190610e56919061224c565b73ffffffffffffffffffffffffffffffffffffffff1603610fc5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b5060009250610f2891505060608a0160408b0161224c565b73ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610f7f576040519150601f19603f3d011682016040523d82523d6000602084013e610f84565b606091505b5050905080610fbf576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611018565b611018610fd860608a0160408b0161224c565b87858881518110610feb57610feb61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611bd39092919063ffffffff16565b61102560e08901896121ae565b868181106110355761103561221d565b905060200201602081019061104a919061224c565b73ffffffffffffffffffffffffffffffffffffffff1661106d60e08a018a6121ae565b600081811061107e5761107e61221d565b9050602002016020810190611093919061224c565b73ffffffffffffffffffffffffffffffffffffffff166110b960e08b0160c08c0161224c565b604080518c358152602081018b905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050505092915050565b6000808061112c60e0860160c0870161224c565b73ffffffffffffffffffffffffffffffffffffffff161490506000816111615761115c60e0860160c0870161224c565b61119a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b90506000806111b0610100880160e0890161224c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576111dc610100870160e0880161224c565b61121a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae91906123a9565b905060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610905061134860405180608001604052808a608001358152602001876113065733611308565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200189815250611904565b80156114335760006113626101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b013560448201526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e91906123c2565b9150508061142b90612415565b965050611522565b60006114476101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b0135604482015273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151291906123c2565b50905061151e81612415565b9650505b61152a611a93565b611543610100890135610c9660808b0160608c0161244d565b86101561157c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d91906123a9565b90508281108061162557506116228784612471565b81105b1561165c576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61169061166f60408b0160208c0161224c565b8561168060608d0160408e0161244d565b61ffff168c61010001358b611b1a565b965060006116a56101008b0160e08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1603611811577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d80600081146117cb576040519150601f19603f3d011682016040523d82523d6000602084013e6117d0565b606091505b505090508061180b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061183f565b61183f61182160208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff86169089611bd3565b6118506101008a0160e08b0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661187660e08b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661189c60408c0160208d0161224c565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c608001358b6040516118f0929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611962576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611af1576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612710611b028382612484565b611b109061ffff16856124a6565b6104f591906124bd565b60006107d0841115611b61576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611b73575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611ba95760646032840204611bac565b60005b9050808303838214611bc457611bc48a8a8484611c65565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611c60908490611d2d565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611d8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e3c9092919063ffffffff16565b9050805160001480611db0575080806020019051810190611db091906124f8565b611c60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611b58565b6060611e4b8484600085611e53565b949350505050565b606082471015611ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611b58565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611f0e919061253e565b60006040518083038185875af1925050503d8060008114611f4b576040519150601f19603f3d011682016040523d82523d6000602084013e611f50565b606091505b5091509150611f6187838387611f6c565b979650505050505050565b60608315612002578251600003611ffb5773ffffffffffffffffffffffffffffffffffffffff85163b611ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611b58565b5081611e4b565b611e4b83838151156120175781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b58919061255a565b6000610120828403121561205e57600080fd5b50919050565b60006020828403121561207657600080fd5b813567ffffffffffffffff81111561208d57600080fd5b611e4b8482850161204b565b6000610140828403121561205e57600080fd5b600061014082840312156120bf57600080fd5b6104f58383612099565b60006040828403121561205e57600080fd5b60008061016083850312156120ef57600080fd5b6120f98484612099565b915061014083013567ffffffffffffffff81111561211657600080fd5b612122858286016120c9565b9150509250929050565b6000806040838503121561213f57600080fd5b823567ffffffffffffffff8082111561215757600080fd5b6121638683870161204b565b9350602085013591508082111561217957600080fd5b50612122858286016120c9565b60006020828403121561219857600080fd5b813565ffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126121e357600080fd5b83018035915067ffffffffffffffff8211156121fe57600080fd5b6020019150600581901b360382131561221657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561225e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122b757600080fd5b83018035915067ffffffffffffffff8211156122d257600080fd5b60200191503681900382131561221657600080fd5b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156123bb57600080fd5b5051919050565b600080604083850312156123d557600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203612446576124466123e6565b5060000390565b60006020828403121561245f57600080fd5b813561ffff811681146104f557600080fd5b80820180821115610249576102496123e6565b61ffff82811682821603908082111561249f5761249f6123e6565b5092915050565b8082028115828204841417610249576102496123e6565b6000826124f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561250a57600080fd5b815180151581146104f557600080fd5b60005b8381101561253557818101518382015260200161251d565b50506000910152565b6000825161255081846020870161251a565b9190910192915050565b602081526000825180602084015261257981604085016020870161251a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122020ef15a82dfe9e15884ad78a08e0e295c6c50a821511c6e99799a1a517eefc3564736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/WarpLink.json b/packages/hardhat/deployments/arbitrum/WarpLink.json index 14a6dd53..d6a939c1 100644 --- a/packages/hardhat/deployments/arbitrum/WarpLink.json +++ b/packages/hardhat/deployments/arbitrum/WarpLink.json @@ -1,5 +1,5 @@ { - "address": "0xC7459df12319E7D46757fb28faE15E45eC2DD5e3", + "address": "0x3f93f837af9390F52D192933782091B1a2808fD2", "abi": [ { "inputs": [], @@ -249,6 +249,71 @@ "stateMutability": "nonpayable", "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" + } + ], + "name": "warpLinkEngage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -326,34 +391,34 @@ "type": "tuple" } ], - "name": "warpLinkEngage", + "name": "warpLinkEngagePermit", "outputs": [], "stateMutability": "payable", "type": "function" } ], - "transactionHash": "0xc7fd58729f89851f96aa0939927efe73969385f5258da8d425b3c62bfedd9b48", + "transactionHash": "0x306344a27272abba2fa99eb533082828673603cfc484c42d94840f3c280e080b", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xC7459df12319E7D46757fb28faE15E45eC2DD5e3", - "transactionIndex": 11, - "gasUsed": "18129863", + "contractAddress": "0x3f93f837af9390F52D192933782091B1a2808fD2", + "transactionIndex": 1, + "gasUsed": "36447927", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x7c35db9e485e7fdce7ad26eab75c6c83f43071cde6bb474c9835504e35f35bae", - "transactionHash": "0xc7fd58729f89851f96aa0939927efe73969385f5258da8d425b3c62bfedd9b48", + "blockHash": "0xec2673c56c1df280704e5fa9a1355954682bfb6d8e81656e6a2926ce7919afbc", + "transactionHash": "0x306344a27272abba2fa99eb533082828673603cfc484c42d94840f3c280e080b", "logs": [], - "blockNumber": 144390195, - "cumulativeGasUsed": "24926692", + "blockNumber": 147606551, + "cumulativeGasUsed": "36447927", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 12, - "solcInputHash": "62b3897f582f2743ff2d0ddfebde07d0", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"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\":\"InvalidSgReceiveSrcAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSgReceiverSender\",\"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\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"bytes\",\"name\":\"_srcAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountLD\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sgReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{\"sgReceive(uint16,bytes,uint256,address,uint256,bytes)\":{\"notice\":\"Cross-chain callback from Stargate The tokens have already been received by this contract, `t.payer` is set to this contract before `sgReceive` is called by the router. The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the same message more than once. The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the Stargate composer be compromised, an attacker can drain this contract. If the payload can not be decoded, tokens are left in this contract. If execution runs out of gas, tokens are left in this contract. If an error occurs during engage, such as insufficient output amount, tokens are refunded to the recipient. See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\"}},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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';\\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\\n bytes payload;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n address paramTokenIn;\\n uint256 paramAmountIn;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint48 paramDeadline;\\n uint256 amount;\\n address payer;\\n address token;\\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 useEth: isFromEth || isToEth,\\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 * Cross-chain callback from Stargate\\n *\\n * The tokens have already been received by this contract, `t.payer` is set to this contract\\n * before `sgReceive` is called by the router.\\n *\\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\\n * same message more than once.\\n *\\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\\n * Stargate composer be compromised, an attacker can drain this contract.\\n *\\n * If the payload can not be decoded, tokens are left in this contract.\\n * If execution runs out of gas, tokens are left in this contract.\\n *\\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\\n * to the recipient.\\n *\\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\\n */\\n function sgReceive(\\n uint16, // _srcChainId\\n bytes memory _srcAddress,\\n uint256, // _nonce\\n address _token,\\n uint256 amountLD,\\n bytes memory payload\\n ) external {\\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\\n revert InvalidSgReceiverSender();\\n }\\n\\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\\n // From https://ethereum.stackexchange.com/a/50528\\n address srcAddress;\\n\\n assembly {\\n srcAddress := mload(add(_srcAddress, 20))\\n }\\n\\n if (srcAddress != address(this)) {\\n // NOTE: This assumes that this contract is deployed at the same address on every chain\\n revert InvalidSgReceiveSrcAddress();\\n }\\n\\n Params memory params = abi.decode(payload, (Params));\\n\\n if (params.tokenIn == address(0)) {\\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\\n // otherwise because `_token` may be different on this chain\\n _token = address(0);\\n }\\n\\n try\\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\\n Params({\\n partner: params.partner,\\n feeBps: params.feeBps,\\n slippageBps: params.slippageBps,\\n recipient: params.recipient,\\n tokenIn: _token,\\n tokenOut: params.tokenOut,\\n amountIn: amountLD,\\n amountOut: params.amountOut,\\n deadline: params.deadline,\\n commands: params.commands\\n }),\\n PermitParams({nonce: 0, signature: ''})\\n )\\n {} catch {\\n // Refund tokens to the recipient\\n if (_token == address(0)) {\\n payable(params.recipient).transfer(amountLD);\\n } else {\\n IERC20(_token).safeTransfer(params.recipient, amountLD);\\n }\\n }\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\\n * in this function.\\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 * - dstGasForCall (uint32)\\n * - tokenOut (address) when `dstGasForCall` > 0\\n * - amountOut (uint256) when `dstGasForCall` > 0\\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n params.dstGasForCall = stream.readUint32();\\n\\n if (params.dstGasForCall > 0) {\\n // NOTE: `amountIn` is left as zero\\n Params memory destParams;\\n destParams.partner = t.paramPartner;\\n destParams.feeBps = t.paramFeeBps;\\n destParams.slippageBps = t.paramSlippageBps;\\n destParams.recipient = t.paramRecipient;\\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\\n // the same address as on this chain\\n destParams.tokenIn = t.token;\\n destParams.tokenOut = stream.readAddress();\\n destParams.amountOut = stream.readUint256();\\n destParams.deadline = t.paramDeadline;\\n destParams.commands = stream.readBytes();\\n params.payload = abi.encode(destParams);\\n }\\n\\n if (t.token != t.paramTokenIn) {\\n if (params.payload.length == 0) {\\n // If the tokens are being delivered directly to the recipient without a second\\n // WarpLink engage, the fee is charged on this chain\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibStarVault.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n }\\n\\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\\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. When there is a payload, the composer is used, else the router\\n IERC20(t.token).forceApprove(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\\n t.amount\\n );\\n }\\n\\n t.jumped = 1;\\n\\n // Swap on the composer if there is a payload, else the router\\n IStargateRouter(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\\n ).swap{\\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\\n }({\\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\\n // more on the other chain. It also assumes the tokens are of nearly equal value\\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: params.dstGasForCall,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n // NOTE: This assumes the contract is deployed at the same address on every chain.\\n // If this is not the case, a new param needs to be added with the next WarpLink address\\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\\n _payload: params.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.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\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 // The signature is omitted when `warpLinkEngage` is called from `sgReceive`\\n if (permit.signature.length > 0) {\\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\\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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0x198e2bb767f975464f62ecb8578721d7516f8da1302b3acfd3c622258de1320e\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\\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 error InvalidSgReceiverSender();\\n error InvalidSgReceiveSrcAddress();\\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\":\"0xc1d8b9ba2a1f8300c00adc2c66fd51da23bb40db78ce5b7fe270bb7ee77e923e\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IStargateReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\n\\ninterface IStargateReceiver {\\n function sgReceive(\\n uint16 _srcChainId, // the remote chainId sending the tokens\\n bytes memory _srcAddress, // the remote Bridge address\\n uint256 _nonce,\\n address _token, // the token contract on the local chain\\n uint256 amountLD, // the qty of local _token contract tokens\\n bytes memory payload\\n ) external;\\n}\\n\",\"keccak256\":\"0x7fd06c09139156a4f09a77eac28e453a1d2041a8cf01a108fc875c65192cb637\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50615400806100206000396000f3fe6080604052600436106100295760003560e01c8063ab8236f31461002e578063dc7b39db14610050575b600080fd5b34801561003a57600080fd5b5061004e610049366004614a1e565b610063565b005b61004e61005e366004614af2565b61036f565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff1633146100d6576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461012a576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906101409190614c9f565b608081015190915073ffffffffffffffffffffffffffffffffffffffff1661016757600094505b3063dc7b39db73ffffffffffffffffffffffffffffffffffffffff871615610190576000610192565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff168152602001856101200151815250604051806040016040528060008152602001604051806020016040528060008152508152506040518463ffffffff1660e01b81526004016102a4929190614efc565b6000604051808303818588803b1580156102bd57600080fd5b505af1935050505080156102cf575060015b6103655773ffffffffffffffffffffffffffffffffffffffff851661033e57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610338573d6000803e3d6000fd5b50610365565b60608101516103659073ffffffffffffffffffffffffffffffffffffffff87169086610981565b5050505050505050565b81610100015165ffffffffffff164211156103b6576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015161ffff9081169184019190915260408086018051831660c08087019182526060808a01518716948801949094526080808a01805188169589019590955290890180519188019190915260e0808a015160a0890152925190941690526101008088015165ffffffffffff169186019190915291519184019190915280518216610140840152511661052a578260c00151341015610509576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08301516105189034614f63565b610180820152306101208201526106bd565b336101208201523461018082015260006105476020840184614f76565b905011156106bd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff1681525085806020019061066b9190614f76565b6040518563ffffffff1660e01b815260040161068a9493929190614fe2565b600060405180830381600087803b1580156106a457600080fd5b505af11580156106b8573d6000803e3d6000fd5b505050505b60006106e2846101200151604080518082019091528181528151909101602082015290565b90506106ee8183610a5a565b61010081015161014082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610755576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107678660e001518760400151610c37565b8210156107a0576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361016001516001036107b557505050505050565b6107d686600001518760a00151886020015161ffff168960e0015186610c65565b915081600003610812576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661087d57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610877573d6000803e3d6000fd5b506108a4565b60608601516108a49073ffffffffffffffffffffffffffffffffffffffff83169084610981565b610180840151156108e257610180840151604051339180156108fc02916000818181858888f193505050501580156108e0573d6000803e3d6000fd5b505b8560a0015173ffffffffffffffffffffffffffffffffffffffff16866080015173ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c0015186604051610971929190918252602082015260400190565b60405180910390a4505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610d1e565b505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526000610ad58480516001018051915290565b60ff16905060005b81811015610c2b576000610af78680516001018051915290565b60ff16905060018103610b1457610b0d85610e2d565b9450610c18565b60028103610b2557610b0d85610ff5565b60038103610b3757610b0d8686611254565b60048103610b4957610b0d8686611832565b60058103610b5b57610b0d8686611bb9565b60068103610b6d57610b0d8686612367565b60078103610b7f57610b0d8686612891565b60088103610b9157610b0d8686612dcf565b60098103610be657610ba4600184614f63565b8214610bdc576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d8686613205565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5080610c23816150a4565b915050610add565b50829150505b92915050565b6000612710610c4683826150dc565b610c549061ffff16856150f7565b610c5e919061513d565b9392505050565b60006107d0841115610cac576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610cbe575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610cf45760646032840204610cf7565b60005b9050808303838214610d0f57610d0f8a8a84846139d7565b50505090910395945050505050565b6000610d80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613a9f9092919063ffffffff16565b9050805160001480610da1575080806020019051810190610da19190615178565b610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ca3565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408082018390526101608201839052610180820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610f0a576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014610f5e576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50959695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146110db576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff8116301480159061110957306101208601525b600061014086015280156111bc57600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505050505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916112199160040190815260200190565b600060405180830381600087803b15801561123357600080fd5b505af1158015611247573d6000803e3d6000fd5b5096979650505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff1661130f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff90911603611404576113ff816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b6114e0565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156114c057600080fd5b505af11580156114d4573d6000803e3d6000fd5b50503061012086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161158657905b606083015161010086015161ffff61271092830316918402908202908101908302816115b4576115b461510e565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e9190615208565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161168457876101000151611687565b60005b866040015161169757600061169e565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561170857600080fd5b505af115801561171c573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b49190615208565b9050818110806117d257506101008701516117cf9083615221565b81105b15611809576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915260006118ad8480516001018051915290565b60ff16905060008361010001519050600060028310156118f9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611b84576000611914600188614f63565b82106119205785611951565b6127106119338b80516002018051915290565b61ffff168a610100015161194791906150f7565b611951919061513d565b90508581111561198d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119978187614f63565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261012080820183815261014080840185815261016085018690526101808501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d015116909152909650611a368b82610a5a565b9050806101600151600103611a77576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611a945780610120015193508061014001519450611b68565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614611afe576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614611b68576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100810151611b789087615221565b955050506001016118ff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152611c4660405180606001604052806060815260200160608152602001606081525090565b6000611c588580516001018051915290565b60ff169050611c68816001615221565b67ffffffffffffffff811115611c8057611c806148ad565b604051908082528060200260200182016040528015611ca9578160200160208202803683370190505b508083526101408501518151909190600090611cc757611cc7615234565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b81811015611d6057855160140180519087528351611d23836001615221565b81518110611d3357611d33615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611d04565b50611d6b8582613ab6565b6020830152611d7a8582613b58565b6040830152815180516000919083908110611d9757611d97615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e319190615208565b90506000611e52846040015187610100015186600001518760200151613be1565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff1603611ee457611edf8460200151600081518110611ea657611ea6615234565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b611fe3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c78516929190600090611f4357611f43615234565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b8152600401611fa9949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015611fc357600080fd5b505af1158015611fd7573d6000803e3d6000fd5b50503061012089015250505b60005b838110156121e7576000611ffb826001615221565b905060008660000151828151811061201557612015615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168760000151848151811061204957612049615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612073576000612076565b60015b90506000600288600001515161208c9190614f63565b841061209857306120b7565b876020015183815181106120ae576120ae615234565b60200260200101515b9050876020015184815181106120cf576120cf615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836121165786858151811061210957612109615234565b6020026020010151612119565b60005b84612125576000612140565b87868151811061213757612137615234565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156121c057600080fd5b505af11580156121d4573d6000803e3d6000fd5b505060019095019450611fe69350505050565b5060008460000151848151811061220057612200615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229a9190615208565b905081600183516122ab9190614f63565b815181106122bb576122bb615234565b602002602001015187610100018181525050828110806122e957506101008701516122e69084615221565b81105b15612320576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845180518590811061233457612334615234565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff90811660208301526101408401511661247a576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156124e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250c9190615208565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff161090506125a86040518060600160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff16815250613e16565b801561268c5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561264f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126739190615263565b9150508061268090615287565b61010087015250612774565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561273c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127609190615263565b50905061276c81615287565b610100870152505b61277c613f7f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e9190615208565b90508281108061282c57506101008601516128299084615221565b81105b15612863576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261291e60405180606001604052806060815260200160608152602001606081525090565b60006129308580516001018051915290565b60ff16905061293f8582613ab6565b825261294b8582613ab6565b60208301528151600090612960600184614f63565b8151811061297057612970615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156129eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0f9190615208565b905060005b83811015612cd75760008115612a4e578551612a31600184614f63565b81518110612a4157612a41615234565b6020026020010151612a55565b8761014001515b905085600001518281518110612a6d57612a6d615234565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516060810182526101008d015181526101208d01518416948101949094529184169183018290521190612ace90613e16565b82600003612ade57306101208a01525b600087602001518481518110612af657612af6615234565b602002602001015190508115612be0576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc79190615263565b91505080612bd490615287565b6101008c015250612cc4565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb09190615263565b509050612cbc81615287565b6101008c0152505b612ccc613f7f565b505050600101612a14565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6e9190615208565b905081811080612d8c5750610100870151612d899083615221565b81105b15612dc3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff9283161592918216159130911614613006577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612fe657600080fd5b505af1158015612ffa573d6000803e3d6000fd5b50503061012088015250505b6000816130a35783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561307a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309e9190615208565b6130a5565b475b9050826130e5576130e5846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff16613fdf9092919063ffffffff16565b61312a84608001518560a0015186602001518661310357600061310a565b8961010001515b886040015189606001518c610100015160008b8061312557508a5b6140d5565b6000826131c75784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561319e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c29190615208565b6131c9565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506131f38282614f63565b61010088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526132a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613431576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff166101008201528451602080820180519092010186526101208201526040516133fc9082906020016152bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613543578060800151516000036134a5578251610140840151602085015161010086015161349e93929161ffff169080610c65565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3866080015187610100015160405161353a929190918252602082015260400190565b60405180910390a45b6135558360a001518460c00151610c37565b8361010001511015613593576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff91821691161561377f5761012084015173ffffffffffffffffffffffffffffffffffffffff1630146136d1577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156136b157600080fd5b505af11580156136c5573d6000803e3d6000fd5b50503061012087015250505b61377f8260800151516000146136e75781613756565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613732573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061375691906152d2565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff169190613fdf565b6001610160850152608082015151156137985780613807565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380791906152d2565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff16146138665785610180015161387c565b85610180015186610100015161387c9190615221565b8451602086015160408701516101008a015160c08b01513091906138a1908290610c37565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c6080015151116138e7578d604001516138e9565b305b604051602001613924919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b16835261399499989796959493926004016152ef565b6000604051808303818588803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b5050600061018088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060613aae84846000856145d1565b949350505050565b60608167ffffffffffffffff811115613ad157613ad16148ad565b604051908082528060200260200182016040528015613afa578160200160208202803683370190505b50905060005b82811015613b515783516014018051908552828281518110613b2457613b24615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613b00565b5092915050565b60608167ffffffffffffffff811115613b7357613b736148ad565b604051908082528060200260200182016040528015613b9c578160200160208202803683370190505b50905060005b82811015613b515783516002018051908552828281518110613bc657613bc6615234565b61ffff90921660209283029190910190910152600101613ba2565b805182516060919067ffffffffffffffff811115613c0157613c016148ad565b604051908082528060200260200182016040528015613c2a578160200160208202803683370190505b5091508482600081518110613c4157613c41615234565b60200260200101818152505060005b81811015613e0c576000858281518110613c6c57613c6c615234565b60200260200101519050600086836001613c869190615221565b81518110613c9657613c96615234565b602002602001015190506000898481518110613cb457613cb4615234565b6020026020010151612710613cc991906150dc565b61ffff169050600080888681518110613ce457613ce4615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d5a91906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115613db557905b828b0282612710020181848d020281613dd057613dd061510e565b049a508a88613de0886001615221565b81518110613df057613df0615234565b6020908102919091010152505060019093019250613c50915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613e74576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613fdd576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261406b84826146ea565b6140cf5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526140c59085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109d3565b6140cf8482610d1e565b50505050565b8860ff1660010361420357871561418e576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561417057600080fd5b505af1158015614184573d6000803e3d6000fd5b50505050506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614157565b8860ff166002036143435787156142ce576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156142a3573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906142c89190615208565b506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614285565b8860ff166003036144e45787156143c1576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614285565b801561443b576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614285565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af11580156144c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c89190615208565b8860ff16600403614594578715614527576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614157565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b606082471015614663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ca3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161468c919061539b565b60006040518083038185875af1925050503d80600081146146c9576040519150601f19603f3d011682016040523d82523d6000602084013e6146ce565b606091505b50915091506146df878383876147ab565b979650505050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614714919061539b565b6000604051808303816000865af19150503d8060008114614751576040519150601f19603f3d011682016040523d82523d6000602084013e614756565b606091505b50915091508180156147805750805115806147805750808060200190518101906147809190615178565b80156147a2575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060831561484157825160000361483a5773ffffffffffffffffffffffffffffffffffffffff85163b61483a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca3565b5081613aae565b613aae83838151156148565781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca391906153b7565b61ffff8116811461489a57600080fd5b50565b80356148a88161488a565b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614900576149006148ad565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561494d5761494d6148ad565b604052919050565b600067ffffffffffffffff82111561496f5761496f6148ad565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149ac57600080fd5b81356149bf6149ba82614955565b614906565b8181528460208386010111156149d457600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461489a57600080fd5b80356148a8816149f1565b60008060008060008060c08789031215614a3757600080fd5b8635614a428161488a565b9550602087013567ffffffffffffffff80821115614a5f57600080fd5b614a6b8a838b0161499b565b96506040890135955060608901359150614a84826149f1565b9093506080880135925060a08801359080821115614aa157600080fd5b50614aae89828a0161499b565b9150509295509295509295565b65ffffffffffff8116811461489a57600080fd5b80356148a881614abb565b600060408284031215614aec57600080fd5b50919050565b60008060408385031215614b0557600080fd5b823567ffffffffffffffff80821115614b1d57600080fd5b908401906101408287031215614b3257600080fd5b614b3a6148dc565b614b4383614a13565b8152614b516020840161489d565b6020820152614b626040840161489d565b6040820152614b7360608401614a13565b6060820152614b8460808401614a13565b6080820152614b9560a08401614a13565b60a082015260c083013560c082015260e083013560e0820152610100614bbc818501614acf565b908201526101208381013583811115614bd457600080fd5b614be08982870161499b565b828401525050809450506020850135915080821115614bfe57600080fd5b50614c0b85828601614ada565b9150509250929050565b80516148a8816149f1565b80516148a88161488a565b80516148a881614abb565b60005b83811015614c51578181015183820152602001614c39565b50506000910152565b600082601f830112614c6b57600080fd5b8151614c796149ba82614955565b818152846020838601011115614c8e57600080fd5b613aae826020830160208701614c36565b600060208284031215614cb157600080fd5b815167ffffffffffffffff80821115614cc957600080fd5b908301906101408286031215614cde57600080fd5b614ce66148dc565b614cef83614c15565b8152614cfd60208401614c20565b6020820152614d0e60408401614c20565b6040820152614d1f60608401614c15565b6060820152614d3060808401614c15565b6080820152614d4160a08401614c15565b60a082015260c083015160c082015260e083015160e0820152610100614d68818501614c2b565b908201526101208381015183811115614d8057600080fd5b614d8c88828701614c5a565b918301919091525095945050505050565b60008151808452614db5816020860160208601614c36565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006101406020830151614e1b602086018261ffff169052565b506040830151614e31604086018261ffff169052565b506060830151614e59606086018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151614e81608086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614ea960a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015160c085015260e083015160e085015261010080840151614ed88287018265ffffffffffff169052565b5050610120808401518282870152614ef283870182614d9d565b9695505050505050565b604081526000614f0f6040830185614de7565b828103602084015283518152602084015160406020830152614ef26040830182614d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c3157610c31614f34565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614fab57600080fd5b83018035915067ffffffffffffffff821115614fc657600080fd5b602001915036819003821315614fdb57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150d5576150d5614f34565b5060010190565b61ffff828116828216039080821115613b5157613b51614f34565b8082028115828204841417610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615173577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561518a57600080fd5b81518015158114610c5e57600080fd5b80516dffffffffffffffffffffffffffff811681146148a857600080fd5b6000806000606084860312156151cd57600080fd5b6151d68461519a565b92506151e46020850161519a565b9150604084015163ffffffff811681146151fd57600080fd5b809150509250925092565b60006020828403121561521a57600080fd5b5051919050565b80820180821115610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561527657600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036152b8576152b8614f34565b5060000390565b602081526000610c5e6020830184614de7565b6000602082840312156152e457600080fd5b8151610c5e816149f1565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615362610180840182614d9d565b905082810360e08401526153768186614d9d565b905082810361010084015261538b8185614d9d565b9c9b505050505050505050505050565b600082516153ad818460208701614c36565b9190910192915050565b602081526000610c5e6020830184614d9d56fea26469706673582212204eecdc76d361ea4a608ec1291a66f39b61f591d844e03c8f4164adb5e8c419c464736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c8063ab8236f31461002e578063dc7b39db14610050575b600080fd5b34801561003a57600080fd5b5061004e610049366004614a1e565b610063565b005b61004e61005e366004614af2565b61036f565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff1633146100d6576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461012a576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906101409190614c9f565b608081015190915073ffffffffffffffffffffffffffffffffffffffff1661016757600094505b3063dc7b39db73ffffffffffffffffffffffffffffffffffffffff871615610190576000610192565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff168152602001856101200151815250604051806040016040528060008152602001604051806020016040528060008152508152506040518463ffffffff1660e01b81526004016102a4929190614efc565b6000604051808303818588803b1580156102bd57600080fd5b505af1935050505080156102cf575060015b6103655773ffffffffffffffffffffffffffffffffffffffff851661033e57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610338573d6000803e3d6000fd5b50610365565b60608101516103659073ffffffffffffffffffffffffffffffffffffffff87169086610981565b5050505050505050565b81610100015165ffffffffffff164211156103b6576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015161ffff9081169184019190915260408086018051831660c08087019182526060808a01518716948801949094526080808a01805188169589019590955290890180519188019190915260e0808a015160a0890152925190941690526101008088015165ffffffffffff169186019190915291519184019190915280518216610140840152511661052a578260c00151341015610509576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08301516105189034614f63565b610180820152306101208201526106bd565b336101208201523461018082015260006105476020840184614f76565b905011156106bd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff1681525085806020019061066b9190614f76565b6040518563ffffffff1660e01b815260040161068a9493929190614fe2565b600060405180830381600087803b1580156106a457600080fd5b505af11580156106b8573d6000803e3d6000fd5b505050505b60006106e2846101200151604080518082019091528181528151909101602082015290565b90506106ee8183610a5a565b61010081015161014082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610755576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107678660e001518760400151610c37565b8210156107a0576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361016001516001036107b557505050505050565b6107d686600001518760a00151886020015161ffff168960e0015186610c65565b915081600003610812576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661087d57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610877573d6000803e3d6000fd5b506108a4565b60608601516108a49073ffffffffffffffffffffffffffffffffffffffff83169084610981565b610180840151156108e257610180840151604051339180156108fc02916000818181858888f193505050501580156108e0573d6000803e3d6000fd5b505b8560a0015173ffffffffffffffffffffffffffffffffffffffff16866080015173ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c0015186604051610971929190918252602082015260400190565b60405180910390a4505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610d1e565b505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526000610ad58480516001018051915290565b60ff16905060005b81811015610c2b576000610af78680516001018051915290565b60ff16905060018103610b1457610b0d85610e2d565b9450610c18565b60028103610b2557610b0d85610ff5565b60038103610b3757610b0d8686611254565b60048103610b4957610b0d8686611832565b60058103610b5b57610b0d8686611bb9565b60068103610b6d57610b0d8686612367565b60078103610b7f57610b0d8686612891565b60088103610b9157610b0d8686612dcf565b60098103610be657610ba4600184614f63565b8214610bdc576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d8686613205565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5080610c23816150a4565b915050610add565b50829150505b92915050565b6000612710610c4683826150dc565b610c549061ffff16856150f7565b610c5e919061513d565b9392505050565b60006107d0841115610cac576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610cbe575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610cf45760646032840204610cf7565b60005b9050808303838214610d0f57610d0f8a8a84846139d7565b50505090910395945050505050565b6000610d80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613a9f9092919063ffffffff16565b9050805160001480610da1575080806020019051810190610da19190615178565b610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ca3565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408082018390526101608201839052610180820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610f0a576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014610f5e576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50959695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146110db576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff8116301480159061110957306101208601525b600061014086015280156111bc57600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505050505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916112199160040190815260200190565b600060405180830381600087803b15801561123357600080fd5b505af1158015611247573d6000803e3d6000fd5b5096979650505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff1661130f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff90911603611404576113ff816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b6114e0565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156114c057600080fd5b505af11580156114d4573d6000803e3d6000fd5b50503061012086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161158657905b606083015161010086015161ffff61271092830316918402908202908101908302816115b4576115b461510e565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e9190615208565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161168457876101000151611687565b60005b866040015161169757600061169e565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561170857600080fd5b505af115801561171c573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b49190615208565b9050818110806117d257506101008701516117cf9083615221565b81105b15611809576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915260006118ad8480516001018051915290565b60ff16905060008361010001519050600060028310156118f9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611b84576000611914600188614f63565b82106119205785611951565b6127106119338b80516002018051915290565b61ffff168a610100015161194791906150f7565b611951919061513d565b90508581111561198d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119978187614f63565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261012080820183815261014080840185815261016085018690526101808501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d015116909152909650611a368b82610a5a565b9050806101600151600103611a77576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611a945780610120015193508061014001519450611b68565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614611afe576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614611b68576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100810151611b789087615221565b955050506001016118ff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152611c4660405180606001604052806060815260200160608152602001606081525090565b6000611c588580516001018051915290565b60ff169050611c68816001615221565b67ffffffffffffffff811115611c8057611c806148ad565b604051908082528060200260200182016040528015611ca9578160200160208202803683370190505b508083526101408501518151909190600090611cc757611cc7615234565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b81811015611d6057855160140180519087528351611d23836001615221565b81518110611d3357611d33615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611d04565b50611d6b8582613ab6565b6020830152611d7a8582613b58565b6040830152815180516000919083908110611d9757611d97615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e319190615208565b90506000611e52846040015187610100015186600001518760200151613be1565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff1603611ee457611edf8460200151600081518110611ea657611ea6615234565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b611fe3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c78516929190600090611f4357611f43615234565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b8152600401611fa9949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015611fc357600080fd5b505af1158015611fd7573d6000803e3d6000fd5b50503061012089015250505b60005b838110156121e7576000611ffb826001615221565b905060008660000151828151811061201557612015615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168760000151848151811061204957612049615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612073576000612076565b60015b90506000600288600001515161208c9190614f63565b841061209857306120b7565b876020015183815181106120ae576120ae615234565b60200260200101515b9050876020015184815181106120cf576120cf615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836121165786858151811061210957612109615234565b6020026020010151612119565b60005b84612125576000612140565b87868151811061213757612137615234565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156121c057600080fd5b505af11580156121d4573d6000803e3d6000fd5b505060019095019450611fe69350505050565b5060008460000151848151811061220057612200615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229a9190615208565b905081600183516122ab9190614f63565b815181106122bb576122bb615234565b602002602001015187610100018181525050828110806122e957506101008701516122e69084615221565b81105b15612320576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845180518590811061233457612334615234565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff90811660208301526101408401511661247a576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156124e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250c9190615208565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff161090506125a86040518060600160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff16815250613e16565b801561268c5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561264f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126739190615263565b9150508061268090615287565b61010087015250612774565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561273c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127609190615263565b50905061276c81615287565b610100870152505b61277c613f7f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e9190615208565b90508281108061282c57506101008601516128299084615221565b81105b15612863576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261291e60405180606001604052806060815260200160608152602001606081525090565b60006129308580516001018051915290565b60ff16905061293f8582613ab6565b825261294b8582613ab6565b60208301528151600090612960600184614f63565b8151811061297057612970615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156129eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0f9190615208565b905060005b83811015612cd75760008115612a4e578551612a31600184614f63565b81518110612a4157612a41615234565b6020026020010151612a55565b8761014001515b905085600001518281518110612a6d57612a6d615234565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516060810182526101008d015181526101208d01518416948101949094529184169183018290521190612ace90613e16565b82600003612ade57306101208a01525b600087602001518481518110612af657612af6615234565b602002602001015190508115612be0576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc79190615263565b91505080612bd490615287565b6101008c015250612cc4565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb09190615263565b509050612cbc81615287565b6101008c0152505b612ccc613f7f565b505050600101612a14565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6e9190615208565b905081811080612d8c5750610100870151612d899083615221565b81105b15612dc3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff9283161592918216159130911614613006577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612fe657600080fd5b505af1158015612ffa573d6000803e3d6000fd5b50503061012088015250505b6000816130a35783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561307a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309e9190615208565b6130a5565b475b9050826130e5576130e5846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff16613fdf9092919063ffffffff16565b61312a84608001518560a0015186602001518661310357600061310a565b8961010001515b886040015189606001518c610100015160008b8061312557508a5b6140d5565b6000826131c75784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561319e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c29190615208565b6131c9565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506131f38282614f63565b61010088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526132a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613431576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff166101008201528451602080820180519092010186526101208201526040516133fc9082906020016152bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613543578060800151516000036134a5578251610140840151602085015161010086015161349e93929161ffff169080610c65565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3866080015187610100015160405161353a929190918252602082015260400190565b60405180910390a45b6135558360a001518460c00151610c37565b8361010001511015613593576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff91821691161561377f5761012084015173ffffffffffffffffffffffffffffffffffffffff1630146136d1577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156136b157600080fd5b505af11580156136c5573d6000803e3d6000fd5b50503061012087015250505b61377f8260800151516000146136e75781613756565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613732573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061375691906152d2565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff169190613fdf565b6001610160850152608082015151156137985780613807565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380791906152d2565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff16146138665785610180015161387c565b85610180015186610100015161387c9190615221565b8451602086015160408701516101008a015160c08b01513091906138a1908290610c37565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c6080015151116138e7578d604001516138e9565b305b604051602001613924919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b16835261399499989796959493926004016152ef565b6000604051808303818588803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b5050600061018088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060613aae84846000856145d1565b949350505050565b60608167ffffffffffffffff811115613ad157613ad16148ad565b604051908082528060200260200182016040528015613afa578160200160208202803683370190505b50905060005b82811015613b515783516014018051908552828281518110613b2457613b24615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613b00565b5092915050565b60608167ffffffffffffffff811115613b7357613b736148ad565b604051908082528060200260200182016040528015613b9c578160200160208202803683370190505b50905060005b82811015613b515783516002018051908552828281518110613bc657613bc6615234565b61ffff90921660209283029190910190910152600101613ba2565b805182516060919067ffffffffffffffff811115613c0157613c016148ad565b604051908082528060200260200182016040528015613c2a578160200160208202803683370190505b5091508482600081518110613c4157613c41615234565b60200260200101818152505060005b81811015613e0c576000858281518110613c6c57613c6c615234565b60200260200101519050600086836001613c869190615221565b81518110613c9657613c96615234565b602002602001015190506000898481518110613cb457613cb4615234565b6020026020010151612710613cc991906150dc565b61ffff169050600080888681518110613ce457613ce4615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d5a91906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115613db557905b828b0282612710020181848d020281613dd057613dd061510e565b049a508a88613de0886001615221565b81518110613df057613df0615234565b6020908102919091010152505060019093019250613c50915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613e74576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613fdd576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261406b84826146ea565b6140cf5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526140c59085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109d3565b6140cf8482610d1e565b50505050565b8860ff1660010361420357871561418e576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561417057600080fd5b505af1158015614184573d6000803e3d6000fd5b50505050506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614157565b8860ff166002036143435787156142ce576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156142a3573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906142c89190615208565b506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614285565b8860ff166003036144e45787156143c1576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614285565b801561443b576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614285565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af11580156144c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c89190615208565b8860ff16600403614594578715614527576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614157565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b606082471015614663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ca3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161468c919061539b565b60006040518083038185875af1925050503d80600081146146c9576040519150601f19603f3d011682016040523d82523d6000602084013e6146ce565b606091505b50915091506146df878383876147ab565b979650505050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614714919061539b565b6000604051808303816000865af19150503d8060008114614751576040519150601f19603f3d011682016040523d82523d6000602084013e614756565b606091505b50915091508180156147805750805115806147805750808060200190518101906147809190615178565b80156147a2575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060831561484157825160000361483a5773ffffffffffffffffffffffffffffffffffffffff85163b61483a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca3565b5081613aae565b613aae83838151156148565781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca391906153b7565b61ffff8116811461489a57600080fd5b50565b80356148a88161488a565b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614900576149006148ad565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561494d5761494d6148ad565b604052919050565b600067ffffffffffffffff82111561496f5761496f6148ad565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149ac57600080fd5b81356149bf6149ba82614955565b614906565b8181528460208386010111156149d457600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461489a57600080fd5b80356148a8816149f1565b60008060008060008060c08789031215614a3757600080fd5b8635614a428161488a565b9550602087013567ffffffffffffffff80821115614a5f57600080fd5b614a6b8a838b0161499b565b96506040890135955060608901359150614a84826149f1565b9093506080880135925060a08801359080821115614aa157600080fd5b50614aae89828a0161499b565b9150509295509295509295565b65ffffffffffff8116811461489a57600080fd5b80356148a881614abb565b600060408284031215614aec57600080fd5b50919050565b60008060408385031215614b0557600080fd5b823567ffffffffffffffff80821115614b1d57600080fd5b908401906101408287031215614b3257600080fd5b614b3a6148dc565b614b4383614a13565b8152614b516020840161489d565b6020820152614b626040840161489d565b6040820152614b7360608401614a13565b6060820152614b8460808401614a13565b6080820152614b9560a08401614a13565b60a082015260c083013560c082015260e083013560e0820152610100614bbc818501614acf565b908201526101208381013583811115614bd457600080fd5b614be08982870161499b565b828401525050809450506020850135915080821115614bfe57600080fd5b50614c0b85828601614ada565b9150509250929050565b80516148a8816149f1565b80516148a88161488a565b80516148a881614abb565b60005b83811015614c51578181015183820152602001614c39565b50506000910152565b600082601f830112614c6b57600080fd5b8151614c796149ba82614955565b818152846020838601011115614c8e57600080fd5b613aae826020830160208701614c36565b600060208284031215614cb157600080fd5b815167ffffffffffffffff80821115614cc957600080fd5b908301906101408286031215614cde57600080fd5b614ce66148dc565b614cef83614c15565b8152614cfd60208401614c20565b6020820152614d0e60408401614c20565b6040820152614d1f60608401614c15565b6060820152614d3060808401614c15565b6080820152614d4160a08401614c15565b60a082015260c083015160c082015260e083015160e0820152610100614d68818501614c2b565b908201526101208381015183811115614d8057600080fd5b614d8c88828701614c5a565b918301919091525095945050505050565b60008151808452614db5816020860160208601614c36565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006101406020830151614e1b602086018261ffff169052565b506040830151614e31604086018261ffff169052565b506060830151614e59606086018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151614e81608086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614ea960a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015160c085015260e083015160e085015261010080840151614ed88287018265ffffffffffff169052565b5050610120808401518282870152614ef283870182614d9d565b9695505050505050565b604081526000614f0f6040830185614de7565b828103602084015283518152602084015160406020830152614ef26040830182614d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c3157610c31614f34565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614fab57600080fd5b83018035915067ffffffffffffffff821115614fc657600080fd5b602001915036819003821315614fdb57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150d5576150d5614f34565b5060010190565b61ffff828116828216039080821115613b5157613b51614f34565b8082028115828204841417610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615173577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561518a57600080fd5b81518015158114610c5e57600080fd5b80516dffffffffffffffffffffffffffff811681146148a857600080fd5b6000806000606084860312156151cd57600080fd5b6151d68461519a565b92506151e46020850161519a565b9150604084015163ffffffff811681146151fd57600080fd5b809150509250925092565b60006020828403121561521a57600080fd5b5051919050565b80820180821115610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561527657600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036152b8576152b8614f34565b5060000390565b602081526000610c5e6020830184614de7565b6000602082840312156152e457600080fd5b8151610c5e816149f1565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615362610180840182614d9d565b905082810360e08401526153768186614d9d565b905082810361010084015261538b8185614d9d565b9c9b505050505050505050505050565b600082516153ad818460208701614c36565b9190910192915050565b602081526000610c5e6020830184614d9d56fea26469706673582212204eecdc76d361ea4a608ec1291a66f39b61f591d844e03c8f4164adb5e8c419c464736f6c63430008130033", + "numDeployments": 13, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"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\":\"InvalidSgReceiveSrcAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSgReceiverSender\",\"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\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"bytes\",\"name\":\"_srcAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountLD\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sgReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"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\":\"warpLinkEngagePermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{\"sgReceive(uint16,bytes,uint256,address,uint256,bytes)\":{\"notice\":\"Cross-chain callback from Stargate The tokens have already been received by this contract, `t.payer` is set to this contract before `sgReceive` is called by the router. The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the same message more than once. The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the Stargate composer be compromised, an attacker can drain this contract. If the payload can not be decoded, tokens are left in this contract. If execution runs out of gas, tokens are left in this contract. If an error occurs during engage, such as insufficient output amount, tokens are refunded to the recipient. See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\"}},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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';\\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\\n bytes payload;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n address paramTokenIn;\\n uint256 paramAmountIn;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint48 paramDeadline;\\n uint256 amount;\\n address payer;\\n address token;\\n /**\\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\\n */\\n uint256 usePermit;\\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 if (t.usePermit == 1) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\\n }\\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 if (t.usePermit == 1) {\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\\n }\\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 if (t.usePermit == 1) {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(\\n t.payer,\\n params.pools[0],\\n (uint160)(t.amount),\\n t.token\\n );\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\\n }\\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({\\n payer: t.payer,\\n token: t.token,\\n amount: t.amount,\\n usePermit: t.usePermit\\n })\\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({\\n payer: t.payer,\\n token: tokenIn,\\n amount: t.amount,\\n usePermit: t.usePermit\\n })\\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 if (t.usePermit == 1) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\\n }\\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 useEth: isFromEth || isToEth,\\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 * Cross-chain callback from Stargate\\n *\\n * The tokens have already been received by this contract, `t.payer` is set to this contract\\n * before `sgReceive` is called by the router.\\n *\\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\\n * same message more than once.\\n *\\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\\n * Stargate composer be compromised, an attacker can drain this contract.\\n *\\n * If the payload can not be decoded, tokens are left in this contract.\\n * If execution runs out of gas, tokens are left in this contract.\\n *\\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\\n * to the recipient.\\n *\\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\\n */\\n function sgReceive(\\n uint16, // _srcChainId\\n bytes memory _srcAddress,\\n uint256, // _nonce\\n address _token,\\n uint256 amountLD,\\n bytes memory payload\\n ) external {\\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\\n revert InvalidSgReceiverSender();\\n }\\n\\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\\n // From https://ethereum.stackexchange.com/a/50528\\n address srcAddress;\\n\\n assembly {\\n srcAddress := mload(add(_srcAddress, 20))\\n }\\n\\n if (srcAddress != address(this)) {\\n // NOTE: This assumes that this contract is deployed at the same address on every chain\\n revert InvalidSgReceiveSrcAddress();\\n }\\n\\n Params memory params = abi.decode(payload, (Params));\\n\\n if (params.tokenIn == address(0)) {\\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\\n // otherwise because `_token` may be different on this chain\\n _token = address(0);\\n }\\n\\n try\\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\\n Params({\\n partner: params.partner,\\n feeBps: params.feeBps,\\n slippageBps: params.slippageBps,\\n recipient: params.recipient,\\n tokenIn: _token,\\n tokenOut: params.tokenOut,\\n amountIn: amountLD,\\n amountOut: params.amountOut,\\n deadline: params.deadline,\\n commands: params.commands\\n })\\n )\\n {} catch {\\n // Refund tokens to the recipient\\n if (_token == address(0)) {\\n payable(params.recipient).transfer(amountLD);\\n } else {\\n IERC20(_token).safeTransfer(params.recipient, amountLD);\\n }\\n }\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\\n * in this function.\\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 * - dstGasForCall (uint32)\\n * - tokenOut (address) when `dstGasForCall` > 0\\n * - amountOut (uint256) when `dstGasForCall` > 0\\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n params.dstGasForCall = stream.readUint32();\\n\\n if (params.dstGasForCall > 0) {\\n // NOTE: `amountIn` is left as zero\\n Params memory destParams;\\n destParams.partner = t.paramPartner;\\n destParams.feeBps = t.paramFeeBps;\\n destParams.slippageBps = t.paramSlippageBps;\\n destParams.recipient = t.paramRecipient;\\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\\n // the same address as on this chain\\n destParams.tokenIn = t.token;\\n destParams.tokenOut = stream.readAddress();\\n destParams.amountOut = stream.readUint256();\\n destParams.deadline = t.paramDeadline;\\n destParams.commands = stream.readBytes();\\n params.payload = abi.encode(destParams);\\n }\\n\\n if (t.token != t.paramTokenIn) {\\n if (params.payload.length == 0) {\\n // If the tokens are being delivered directly to the recipient without a second\\n // WarpLink engage, the fee is charged on this chain\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibStarVault.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n }\\n\\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\\n\\n if (t.token != address(0)) {\\n if (t.payer != address(this)) {\\n if (t.usePermit == 1) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n t.payer,\\n address(this),\\n (uint160)(t.amount),\\n t.token\\n );\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\\n }\\n\\n // Update the payer to this contract\\n // TODO: Is this value ever read?\\n t.payer = address(this);\\n }\\n\\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\\n IERC20(t.token).forceApprove(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\\n t.amount\\n );\\n }\\n\\n t.jumped = 1;\\n\\n // Swap on the composer if there is a payload, else the router\\n IStargateRouter(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\\n ).swap{\\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\\n }({\\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\\n // more on the other chain. It also assumes the tokens are of nearly equal value\\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: params.dstGasForCall,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n // NOTE: This assumes the contract is deployed at the same address on every chain.\\n // If this is not the case, a new param needs to be added with the next WarpLink address\\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\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\\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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function warpLinkEngagePermit(\\n Params calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n TransientState memory t;\\n t.paramPartner = params.partner;\\n t.paramFeeBps = params.feeBps;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.usePermit = 1;\\n\\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 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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0xafd9df86ea5bc03ea83d33890bbbe7e383f84bec96e5b67dd99e7d717bc9bcb3\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\\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 error InvalidSgReceiverSender();\\n error InvalidSgReceiveSrcAddress();\\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 calldata params) external payable;\\n\\n function warpLinkEngagePermit(\\n Params calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n}\\n\",\"keccak256\":\"0x0eff4788d9f45d72b6a05f34f1e8236a6f9d76a4778396d9a53c66ec04ebf726\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IStargateReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\n\\ninterface IStargateReceiver {\\n function sgReceive(\\n uint16 _srcChainId, // the remote chainId sending the tokens\\n bytes memory _srcAddress, // the remote Bridge address\\n uint256 _nonce,\\n address _token, // the token contract on the local chain\\n uint256 amountLD, // the qty of local _token contract tokens\\n bytes memory payload\\n ) external;\\n}\\n\",\"keccak256\":\"0x7fd06c09139156a4f09a77eac28e453a1d2041a8cf01a108fc875c65192cb637\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50615c3880620000216000396000f3fe6080604052600436106100345760003560e01c8063a703fc4014610039578063ab8236f31461004e578063dcc455511461006e575b600080fd5b61004c610047366004615184565b610081565b005b34801561005a57600080fd5b5061004c610069366004615368565b6106c6565b61004c61007c366004615405565b6109ac565b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152906100fd9084018461543a565b73ffffffffffffffffffffffffffffffffffffffff1681526101256040840160208501615457565b61ffff16602082015261013e6060840160408501615457565b61ffff1660c0820152610157608084016060850161543a565b73ffffffffffffffffffffffffffffffffffffffff16604082015261018260a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0840135608083015260e084013560a08301526101c490840160408501615457565b61ffff1660c08201526101df61012084016101008501615488565b65ffffffffffff1660e082015260c083013561010082015261020760a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff9081166101408301526001610160830152336101208301819052346101a08401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e08101909152921691632b67b570919080606081018061028a60a08b0160808c0161543a565b73ffffffffffffffffffffffffffffffffffffffff908116825260c08b01351660208201526040016102c46101208b016101008c01615488565b65ffffffffffff908116825289351660209182015290825230908201526040016102f661012089016101008a01615488565b65ffffffffffff16905261030d60208701876154a5565b6040518563ffffffff1660e01b815260040161032c9493929190615511565b600060405180830381600087803b15801561034657600080fd5b505af115801561035a573d6000803e3d6000fd5b5050505060006103ae8480610120019061037491906154a5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f4192505050565b90506103ba8183610f5b565b610100810151610140820151919350906103da60c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043e576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61045b60e08701356104566060890160408a01615457565b611140565b821015610494576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361018001516001036104a957505050505050565b6104e86104b9602088018861543a565b6104c960c0890160a08a0161543a565b6104d960408a0160208b01615457565b61ffff168960e001358661116e565b915081600003610524576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661059a5761054f608087016060880161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610594573d6000803e3d6000fd5b506105cb565b6105cb6105ad608088016060890161543a565b73ffffffffffffffffffffffffffffffffffffffff83169084611227565b6101a084015115610609576101a0840151604051339180156108fc02916000818181858888f19350505050158015610607573d6000803e3d6000fd5b505b61061960c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff1661063f60a088016080890161543a565b73ffffffffffffffffffffffffffffffffffffffff16610662602089018961543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c00135866040516106b6929190918252602082015260400190565b60405180910390a4505050505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461078d576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906107a39190615662565b608081015190915073ffffffffffffffffffffffffffffffffffffffff166107ca57600094505b3063dcc4555173ffffffffffffffffffffffffffffffffffffffff8716156107f35760006107f5565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff1681526020018561012001518152506040518363ffffffff1660e01b81526004016108e191906157aa565b6000604051808303818588803b1580156108fa57600080fd5b505af19350505050801561090c575060015b6109a25773ffffffffffffffffffffffffffffffffffffffff851661097b57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610975573d6000803e3d6000fd5b506109a2565b60608101516109a29073ffffffffffffffffffffffffffffffffffffffff87169086611227565b5050505050505050565b6109be61012082016101008301615488565b65ffffffffffff164211156109ff576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082015290610a7b9083018361543a565b73ffffffffffffffffffffffffffffffffffffffff168152610aa36040830160208401615457565b61ffff166020820152610abc6060830160408401615457565b61ffff1660c0820152610ad5608083016060840161543a565b73ffffffffffffffffffffffffffffffffffffffff166040820152610b0060a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0830135608083015260e083013560a0830152610b4290830160408401615457565b61ffff1660c0820152610b5d61012083016101008401615488565b65ffffffffffff1660e082015260c0820135610100820152610b8560a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff166101408201526000610bb360a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1603610c2c578160c00135341015610c0c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c1a60c0830135346158dc565b6101a082015230610120820152610c3b565b33610120820152346101a08201525b6000610c4e6103746101208501856154a5565b9050610c5a8183610f5b565b61010081015161014082015191935090610c7a60c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cde576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cf660e08601356104566060880160408901615457565b821015610d2f576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836101800151600103610d43575050505050565b610d82610d53602087018761543a565b610d6360c0880160a0890161543a565b610d736040890160208a01615457565b61ffff168860e001358661116e565b915081600003610dbe576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e3457610de9608086016060870161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610e2e573d6000803e3d6000fd5b50610e47565b610e476105ad608087016060880161543a565b6101a084015115610e85576101a0840151604051339180156108fc02916000818181858888f19350505050158015610e83573d6000803e3d6000fd5b505b610e9560c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ebb60a087016080880161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ede602088018861543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38860c0013586604051610f32929190918252602082015260400190565b60405180910390a45050505050565b604080518082019091528181528151909101602082015290565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000610fde8480516001018051915290565b60ff16905060005b818110156111345760006110008680516001018051915290565b60ff1690506001810361101d5761101685611300565b9450611121565b6002810361102e57611016856114d0565b600381036110405761101686866117f2565b60048103611052576110168686611e2a565b600581036110645761101686866121c1565b600681036110765761101686866129e3565b60078103611088576110168686612f20565b6008810361109a576110168686613471565b600981036110ef576110ad6001846158dc565b82146110e5576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61101686866138fd565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061112c816158ef565b915050610fe6565b50829150505b92915050565b600061271061114f8382615927565b61115d9061ffff1685615942565b6111679190615988565b9392505050565b60006107d08411156111b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156111c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156111fd5760646032840204611200565b60005b9050808303838214611218576112188a8a8484614125565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112fb9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526141ed565b505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140808201839052610160820183905261018082018390526101a0820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff16156113e5576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014611439576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b1580156114b057600080fd5b505af11580156114c4573d6000803e3d6000fd5b50959695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146115be576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff811630148015906115ec57306101208601525b6000610140860152801561175a578461016001516001036116b057600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b5050505061175a565b82546101008601516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015611734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175891906159c3565b505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916117b79160040190815260200190565b600060405180830381600087803b1580156117d157600080fd5b505af11580156117e5573d6000803e3d6000fd5b5096979650505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff166118b5576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff909116036119aa576119a5816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b611ad8565b826101600151600103611a90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015611a7357600080fd5b505af1158015611a87573d6000803e3d6000fd5b50505050611ad0565b611ad0836101200151826020015185610100015186610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208401525b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151611b7e57905b606083015161010086015161ffff6127109283031691840290820290810190830281611bac57611bac615959565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c469190615a53565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8560400151611c7c57876101000151611c7f565b60005b8660400151611c8f576000611c96565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015611d0057600080fd5b505af1158015611d14573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190615a53565b905081811080611dca5750610100870151611dc79083615a6c565b81105b15611e01576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000611ead8480516001018051915290565b60ff1690506000836101000151905060006002831015611ef9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561218c576000611f146001886158dc565b8210611f205785611f51565b612710611f338b80516002018051915290565b61ffff168a6101000151611f479190615942565b611f519190615988565b905085811115611f8d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f9781876158dc565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610120808201838152610140808401858152610160850186905261018085018690526101a08501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d01511690915290965061203e8b82610f5b565b905080610180015160010361207f576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361209c5780610120015193508061014001519450612170565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614612106576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614612170576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008101516121809087615a6c565b95505050600101611eff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261225660405180606001604052806060815260200160608152602001606081525090565b60006122688580516001018051915290565b60ff169050612278816001615a6c565b67ffffffffffffffff81111561229057612290615202565b6040519080825280602002602001820160405280156122b9578160200160208202803683370190505b5080835261014085015181519091906000906122d7576122d7615a7f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561237057855160140180519087528351612333836001615a6c565b8151811061234357612343615a7f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612314565b5061237b8582614360565b602083015261238a8582614402565b60408301528151805160009190839081106123a7576123a7615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615a53565b9050600061246284604001518761010001518660000151876020015161448b565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff16036124f4576124ef84602001516000815181106124b6576124b6615a7f565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b61265f565b8561016001516001036125fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061256057612560615a7f565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b81526004016125c6949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b50505050612657565b612657866101200151856020015160008151811061261d5761261d615a7f565b602002602001015188610100015189610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208701525b60005b83811015612863576000612677826001615a6c565b905060008660000151828151811061269157612691615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16876000015184815181106126c5576126c5615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106126ef5760006126f2565b60015b90506000600288600001515161270891906158dc565b84106127145730612733565b8760200151838151811061272a5761272a615a7f565b60200260200101515b90508760200151848151811061274b5761274b615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836127925786858151811061278557612785615a7f565b6020026020010151612795565b60005b846127a15760006127bc565b8786815181106127b3576127b3615a7f565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561283c57600080fd5b505af1158015612850573d6000803e3d6000fd5b5050600190950194506126629350505050565b5060008460000151848151811061287c5761287c615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129169190615a53565b9050816001835161292791906158dc565b8151811061293757612937615a7f565b6020026020010151876101000181815250508281108061296557506101008701516129629084615a6c565b81105b1561299c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518051859081106129b0576129b0615a7f565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015261014084015116612afe576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190615a53565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff16109050612c376040518060800160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018761016001518152506146c0565b8015612d1b5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d029190615aae565b91505080612d0f90615ad2565b61010087015250612e03565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def9190615aae565b509050612dfb81615ad2565b610100870152505b612e0b61484f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615a53565b905082811080612ebb5750610100860151612eb89084615a6c565b81105b15612ef2576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a0810191909152612fb560405180606001604052806060815260200160608152602001606081525090565b6000612fc78580516001018051915290565b60ff169050612fd68582614360565b8252612fe28582614360565b60208301528151600090612ff76001846158dc565b8151811061300757613007615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190615a53565b905060005b8381101561337957600081156130e55785516130c86001846158dc565b815181106130d8576130d8615a7f565b60200260200101516130ec565b8761014001515b90508560000151828151811061310457613104615a7f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516080810182526101008d015181526101208d01518416948101949094529184169183018290526101608b015160608401521190613170906146c0565b8260000361318057306101208a01525b60008760200151848151811061319857613198615a7f565b602002602001015190508115613282576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615aae565b9150508061327690615ad2565b6101008c015250613366565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561332e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133529190615aae565b50905061335e81615ad2565b6101008c0152505b61336e61484f565b5050506001016130ab565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156133ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134109190615a53565b90508181108061342e575061010087015161342b9083615a6c565b81105b15613465576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146136fe578461016001516001036136ba577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561369d57600080fd5b505af11580156136b1573d6000803e3d6000fd5b505050506136f6565b6136f68561012001513087610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208601525b60008161379b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137969190615a53565b61379d565b475b9050826137dd576137dd846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166148af9092919063ffffffff16565b61382284608001518560a001518660200151866137fb576000613802565b8961010001515b886040015189606001518c610100015160008b8061381d57508a5b61499f565b6000826138bf5784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ba9190615a53565b6138c1565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506138eb82826158dc565b61010088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526139a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613b31576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff16610100820152845160208082018051909201018652610120820152604051613afc9082906020016157aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613c4357806080015151600003613ba55782516101408401516020850151610100860151613b9e93929161ffff16908061116e565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38660800151876101000151604051613c3a929190918252602082015260400190565b60405180910390a45b613c558360a001518460c00151611140565b8361010001511015613c93576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff918216911615613ecd5761012084015173ffffffffffffffffffffffffffffffffffffffff163014613e1f57836101600151600103613ddb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015613dbe57600080fd5b505af1158015613dd2573d6000803e3d6000fd5b50505050613e17565b613e178461012001513086610100015187610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208501525b613ecd826080015151600014613e355781613ea4565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea49190615b0a565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff1691906148af565b600161018085015260808201515115613ee65780613f55565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f559190615b0a565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff1614613fb457856101a00151613fca565b856101a00151866101000151613fca9190615a6c565b8451602086015160408701516101008a015160c08b0151309190613fef908290611140565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c608001515111614035578d60400151614037565b305b604051602001614072919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b1683526140e29998979695949392600401615b27565b6000604051808303818588803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b505060006101a088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b600061424f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614e9b9092919063ffffffff16565b905080516000148061427057508080602001905181019061427091906159c3565b6112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016111ac565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261435a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611279565b50505050565b60608167ffffffffffffffff81111561437b5761437b615202565b6040519080825280602002602001820160405280156143a4578160200160208202803683370190505b50905060005b828110156143fb57835160140180519085528282815181106143ce576143ce615a7f565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016143aa565b5092915050565b60608167ffffffffffffffff81111561441d5761441d615202565b604051908082528060200260200182016040528015614446578160200160208202803683370190505b50905060005b828110156143fb578351600201805190855282828151811061447057614470615a7f565b61ffff9092166020928302919091019091015260010161444c565b805182516060919067ffffffffffffffff8111156144ab576144ab615202565b6040519080825280602002602001820160405280156144d4578160200160208202803683370190505b50915084826000815181106144eb576144eb615a7f565b60200260200101818152505060005b818110156146b657600085828151811061451657614516615a7f565b602002602001015190506000868360016145309190615a6c565b8151811061454057614540615a7f565b60200260200101519050600089848151811061455e5761455e615a7f565b60200260200101516127106145739190615927565b61ffff16905060008088868151811061458e5761458e615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156145e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146049190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561465f57905b828b0282612710020181848d02028161467a5761467a615959565b049a508a8861468a886001615a6c565b8151811061469a5761469a615a7f565b60209081029190910101525050600190930192506144fa915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361471e576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036148ad576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261493b8482614eb2565b61435a5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526149959085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611279565b61435a84826141ed565b8860ff16600103614acd578715614a58576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015614a3a57600080fd5b505af1158015614a4e573d6000803e3d6000fd5b5050505050614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614a21565b8860ff16600203614c0d578715614b98576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015614b6d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190614b929190615a53565b50614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614b4f565b8860ff16600303614dae578715614c8b576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614b4f565b8015614d05576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614b4f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015614d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b929190615a53565b8860ff16600403614e5e578715614df1576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614a21565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6060614eaa8484600085614f73565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614edc9190615bd3565b6000604051808303816000865af19150503d8060008114614f19576040519150601f19603f3d011682016040523d82523d6000602084013e614f1e565b606091505b5091509150818015614f48575080511580614f48575080806020019051810190614f4891906159c3565b8015614f6a575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b606082471015615005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016111ac565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161502e9190615bd3565b60006040518083038185875af1925050503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b50915091506150818783838761508c565b979650505050505050565b6060831561512257825160000361511b5773ffffffffffffffffffffffffffffffffffffffff85163b61511b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016111ac565b5081614eaa565b614eaa83838151156151375781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac9190615bef565b6000610140828403121561517e57600080fd5b50919050565b6000806040838503121561519757600080fd5b823567ffffffffffffffff808211156151af57600080fd5b6151bb8683870161516b565b935060208501359150808211156151d157600080fd5b508301604081860312156151e457600080fd5b809150509250929050565b61ffff811681146151ff57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561525557615255615202565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156152a2576152a2615202565b604052919050565b600067ffffffffffffffff8211156152c4576152c4615202565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261530157600080fd5b813561531461530f826152aa565b61525b565b81815284602083860101111561532957600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146151ff57600080fd5b60008060008060008060c0878903121561538157600080fd5b863561538c816151ef565b9550602087013567ffffffffffffffff808211156153a957600080fd5b6153b58a838b016152f0565b965060408901359550606089013591506153ce82615346565b9093506080880135925060a088013590808211156153eb57600080fd5b506153f889828a016152f0565b9150509295509295509295565b60006020828403121561541757600080fd5b813567ffffffffffffffff81111561542e57600080fd5b614eaa8482850161516b565b60006020828403121561544c57600080fd5b813561116781615346565b60006020828403121561546957600080fd5b8135611167816151ef565b65ffffffffffff811681146151ff57600080fd5b60006020828403121561549a57600080fd5b813561116781615474565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154da57600080fd5b83018035915067ffffffffffffffff8211156154f557600080fd5b60200191503681900382131561550a57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b80516155de81615346565b919050565b80516155de816151ef565b80516155de81615474565b60005b838110156156145781810151838201526020016155fc565b50506000910152565b600082601f83011261562e57600080fd5b815161563c61530f826152aa565b81815284602083860101111561565157600080fd5b614eaa8260208301602087016155f9565b60006020828403121561567457600080fd5b815167ffffffffffffffff8082111561568c57600080fd5b9083019061014082860312156156a157600080fd5b6156a9615231565b6156b2836155d3565b81526156c0602084016155e3565b60208201526156d1604084016155e3565b60408201526156e2606084016155d3565b60608201526156f3608084016155d3565b608082015261570460a084016155d3565b60a082015260c083015160c082015260e083015160e082015261010061572b8185016155ee565b90820152610120838101518381111561574357600080fd5b61574f8882870161561d565b918301919091525095945050505050565b600081518084526157788160208601602086016155f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526157d160208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516157e8604084018261ffff169052565b50604083015161ffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c083015160e083015260e08301516101008181850152808501519150506101206158938185018365ffffffffffff169052565b840151610140848101529050614eaa610160840182615760565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561113a5761113a6158ad565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615920576159206158ad565b5060010190565b61ffff8281168282160390808211156143fb576143fb6158ad565b808202811582820484141761113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156159d557600080fd5b8151801515811461116757600080fd5b80516dffffffffffffffffffffffffffff811681146155de57600080fd5b600080600060608486031215615a1857600080fd5b615a21846159e5565b9250615a2f602085016159e5565b9150604084015163ffffffff81168114615a4857600080fd5b809150509250925092565b600060208284031215615a6557600080fd5b5051919050565b8082018082111561113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215615ac157600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b0357615b036158ad565b5060000390565b600060208284031215615b1c57600080fd5b815161116781615346565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615b9a610180840182615760565b905082810360e0840152615bae8186615760565b9050828103610100840152615bc38185615760565b9c9b505050505050505050505050565b60008251615be58184602087016155f9565b9190910192915050565b602081526000611167602083018461576056fea26469706673582212202ce6a8f21a153c83c150806f9ce2e260656621d27c2de20b34fdaa1dbce5be3f64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c8063a703fc4014610039578063ab8236f31461004e578063dcc455511461006e575b600080fd5b61004c610047366004615184565b610081565b005b34801561005a57600080fd5b5061004c610069366004615368565b6106c6565b61004c61007c366004615405565b6109ac565b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152906100fd9084018461543a565b73ffffffffffffffffffffffffffffffffffffffff1681526101256040840160208501615457565b61ffff16602082015261013e6060840160408501615457565b61ffff1660c0820152610157608084016060850161543a565b73ffffffffffffffffffffffffffffffffffffffff16604082015261018260a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0840135608083015260e084013560a08301526101c490840160408501615457565b61ffff1660c08201526101df61012084016101008501615488565b65ffffffffffff1660e082015260c083013561010082015261020760a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff9081166101408301526001610160830152336101208301819052346101a08401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e08101909152921691632b67b570919080606081018061028a60a08b0160808c0161543a565b73ffffffffffffffffffffffffffffffffffffffff908116825260c08b01351660208201526040016102c46101208b016101008c01615488565b65ffffffffffff908116825289351660209182015290825230908201526040016102f661012089016101008a01615488565b65ffffffffffff16905261030d60208701876154a5565b6040518563ffffffff1660e01b815260040161032c9493929190615511565b600060405180830381600087803b15801561034657600080fd5b505af115801561035a573d6000803e3d6000fd5b5050505060006103ae8480610120019061037491906154a5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f4192505050565b90506103ba8183610f5b565b610100810151610140820151919350906103da60c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043e576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61045b60e08701356104566060890160408a01615457565b611140565b821015610494576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361018001516001036104a957505050505050565b6104e86104b9602088018861543a565b6104c960c0890160a08a0161543a565b6104d960408a0160208b01615457565b61ffff168960e001358661116e565b915081600003610524576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661059a5761054f608087016060880161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610594573d6000803e3d6000fd5b506105cb565b6105cb6105ad608088016060890161543a565b73ffffffffffffffffffffffffffffffffffffffff83169084611227565b6101a084015115610609576101a0840151604051339180156108fc02916000818181858888f19350505050158015610607573d6000803e3d6000fd5b505b61061960c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff1661063f60a088016080890161543a565b73ffffffffffffffffffffffffffffffffffffffff16610662602089018961543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c00135866040516106b6929190918252602082015260400190565b60405180910390a4505050505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461078d576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906107a39190615662565b608081015190915073ffffffffffffffffffffffffffffffffffffffff166107ca57600094505b3063dcc4555173ffffffffffffffffffffffffffffffffffffffff8716156107f35760006107f5565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff1681526020018561012001518152506040518363ffffffff1660e01b81526004016108e191906157aa565b6000604051808303818588803b1580156108fa57600080fd5b505af19350505050801561090c575060015b6109a25773ffffffffffffffffffffffffffffffffffffffff851661097b57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610975573d6000803e3d6000fd5b506109a2565b60608101516109a29073ffffffffffffffffffffffffffffffffffffffff87169086611227565b5050505050505050565b6109be61012082016101008301615488565b65ffffffffffff164211156109ff576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082015290610a7b9083018361543a565b73ffffffffffffffffffffffffffffffffffffffff168152610aa36040830160208401615457565b61ffff166020820152610abc6060830160408401615457565b61ffff1660c0820152610ad5608083016060840161543a565b73ffffffffffffffffffffffffffffffffffffffff166040820152610b0060a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0830135608083015260e083013560a0830152610b4290830160408401615457565b61ffff1660c0820152610b5d61012083016101008401615488565b65ffffffffffff1660e082015260c0820135610100820152610b8560a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff166101408201526000610bb360a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1603610c2c578160c00135341015610c0c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c1a60c0830135346158dc565b6101a082015230610120820152610c3b565b33610120820152346101a08201525b6000610c4e6103746101208501856154a5565b9050610c5a8183610f5b565b61010081015161014082015191935090610c7a60c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cde576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cf660e08601356104566060880160408901615457565b821015610d2f576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836101800151600103610d43575050505050565b610d82610d53602087018761543a565b610d6360c0880160a0890161543a565b610d736040890160208a01615457565b61ffff168860e001358661116e565b915081600003610dbe576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e3457610de9608086016060870161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610e2e573d6000803e3d6000fd5b50610e47565b610e476105ad608087016060880161543a565b6101a084015115610e85576101a0840151604051339180156108fc02916000818181858888f19350505050158015610e83573d6000803e3d6000fd5b505b610e9560c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ebb60a087016080880161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ede602088018861543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38860c0013586604051610f32929190918252602082015260400190565b60405180910390a45050505050565b604080518082019091528181528151909101602082015290565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000610fde8480516001018051915290565b60ff16905060005b818110156111345760006110008680516001018051915290565b60ff1690506001810361101d5761101685611300565b9450611121565b6002810361102e57611016856114d0565b600381036110405761101686866117f2565b60048103611052576110168686611e2a565b600581036110645761101686866121c1565b600681036110765761101686866129e3565b60078103611088576110168686612f20565b6008810361109a576110168686613471565b600981036110ef576110ad6001846158dc565b82146110e5576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61101686866138fd565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061112c816158ef565b915050610fe6565b50829150505b92915050565b600061271061114f8382615927565b61115d9061ffff1685615942565b6111679190615988565b9392505050565b60006107d08411156111b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156111c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156111fd5760646032840204611200565b60005b9050808303838214611218576112188a8a8484614125565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112fb9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526141ed565b505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140808201839052610160820183905261018082018390526101a0820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff16156113e5576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014611439576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b1580156114b057600080fd5b505af11580156114c4573d6000803e3d6000fd5b50959695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146115be576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff811630148015906115ec57306101208601525b6000610140860152801561175a578461016001516001036116b057600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b5050505061175a565b82546101008601516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015611734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175891906159c3565b505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916117b79160040190815260200190565b600060405180830381600087803b1580156117d157600080fd5b505af11580156117e5573d6000803e3d6000fd5b5096979650505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff166118b5576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff909116036119aa576119a5816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b611ad8565b826101600151600103611a90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015611a7357600080fd5b505af1158015611a87573d6000803e3d6000fd5b50505050611ad0565b611ad0836101200151826020015185610100015186610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208401525b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151611b7e57905b606083015161010086015161ffff6127109283031691840290820290810190830281611bac57611bac615959565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c469190615a53565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8560400151611c7c57876101000151611c7f565b60005b8660400151611c8f576000611c96565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015611d0057600080fd5b505af1158015611d14573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190615a53565b905081811080611dca5750610100870151611dc79083615a6c565b81105b15611e01576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000611ead8480516001018051915290565b60ff1690506000836101000151905060006002831015611ef9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561218c576000611f146001886158dc565b8210611f205785611f51565b612710611f338b80516002018051915290565b61ffff168a6101000151611f479190615942565b611f519190615988565b905085811115611f8d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f9781876158dc565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610120808201838152610140808401858152610160850186905261018085018690526101a08501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d01511690915290965061203e8b82610f5b565b905080610180015160010361207f576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361209c5780610120015193508061014001519450612170565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614612106576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614612170576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008101516121809087615a6c565b95505050600101611eff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261225660405180606001604052806060815260200160608152602001606081525090565b60006122688580516001018051915290565b60ff169050612278816001615a6c565b67ffffffffffffffff81111561229057612290615202565b6040519080825280602002602001820160405280156122b9578160200160208202803683370190505b5080835261014085015181519091906000906122d7576122d7615a7f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561237057855160140180519087528351612333836001615a6c565b8151811061234357612343615a7f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612314565b5061237b8582614360565b602083015261238a8582614402565b60408301528151805160009190839081106123a7576123a7615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615a53565b9050600061246284604001518761010001518660000151876020015161448b565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff16036124f4576124ef84602001516000815181106124b6576124b6615a7f565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b61265f565b8561016001516001036125fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061256057612560615a7f565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b81526004016125c6949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b50505050612657565b612657866101200151856020015160008151811061261d5761261d615a7f565b602002602001015188610100015189610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208701525b60005b83811015612863576000612677826001615a6c565b905060008660000151828151811061269157612691615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16876000015184815181106126c5576126c5615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106126ef5760006126f2565b60015b90506000600288600001515161270891906158dc565b84106127145730612733565b8760200151838151811061272a5761272a615a7f565b60200260200101515b90508760200151848151811061274b5761274b615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836127925786858151811061278557612785615a7f565b6020026020010151612795565b60005b846127a15760006127bc565b8786815181106127b3576127b3615a7f565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561283c57600080fd5b505af1158015612850573d6000803e3d6000fd5b5050600190950194506126629350505050565b5060008460000151848151811061287c5761287c615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129169190615a53565b9050816001835161292791906158dc565b8151811061293757612937615a7f565b6020026020010151876101000181815250508281108061296557506101008701516129629084615a6c565b81105b1561299c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518051859081106129b0576129b0615a7f565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015261014084015116612afe576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190615a53565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff16109050612c376040518060800160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018761016001518152506146c0565b8015612d1b5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d029190615aae565b91505080612d0f90615ad2565b61010087015250612e03565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def9190615aae565b509050612dfb81615ad2565b610100870152505b612e0b61484f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615a53565b905082811080612ebb5750610100860151612eb89084615a6c565b81105b15612ef2576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a0810191909152612fb560405180606001604052806060815260200160608152602001606081525090565b6000612fc78580516001018051915290565b60ff169050612fd68582614360565b8252612fe28582614360565b60208301528151600090612ff76001846158dc565b8151811061300757613007615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190615a53565b905060005b8381101561337957600081156130e55785516130c86001846158dc565b815181106130d8576130d8615a7f565b60200260200101516130ec565b8761014001515b90508560000151828151811061310457613104615a7f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516080810182526101008d015181526101208d01518416948101949094529184169183018290526101608b015160608401521190613170906146c0565b8260000361318057306101208a01525b60008760200151848151811061319857613198615a7f565b602002602001015190508115613282576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615aae565b9150508061327690615ad2565b6101008c015250613366565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561332e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133529190615aae565b50905061335e81615ad2565b6101008c0152505b61336e61484f565b5050506001016130ab565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156133ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134109190615a53565b90508181108061342e575061010087015161342b9083615a6c565b81105b15613465576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146136fe578461016001516001036136ba577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561369d57600080fd5b505af11580156136b1573d6000803e3d6000fd5b505050506136f6565b6136f68561012001513087610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208601525b60008161379b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137969190615a53565b61379d565b475b9050826137dd576137dd846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166148af9092919063ffffffff16565b61382284608001518560a001518660200151866137fb576000613802565b8961010001515b886040015189606001518c610100015160008b8061381d57508a5b61499f565b6000826138bf5784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ba9190615a53565b6138c1565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506138eb82826158dc565b61010088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526139a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613b31576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff16610100820152845160208082018051909201018652610120820152604051613afc9082906020016157aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613c4357806080015151600003613ba55782516101408401516020850151610100860151613b9e93929161ffff16908061116e565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38660800151876101000151604051613c3a929190918252602082015260400190565b60405180910390a45b613c558360a001518460c00151611140565b8361010001511015613c93576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff918216911615613ecd5761012084015173ffffffffffffffffffffffffffffffffffffffff163014613e1f57836101600151600103613ddb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015613dbe57600080fd5b505af1158015613dd2573d6000803e3d6000fd5b50505050613e17565b613e178461012001513086610100015187610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208501525b613ecd826080015151600014613e355781613ea4565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea49190615b0a565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff1691906148af565b600161018085015260808201515115613ee65780613f55565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f559190615b0a565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff1614613fb457856101a00151613fca565b856101a00151866101000151613fca9190615a6c565b8451602086015160408701516101008a015160c08b0151309190613fef908290611140565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c608001515111614035578d60400151614037565b305b604051602001614072919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b1683526140e29998979695949392600401615b27565b6000604051808303818588803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b505060006101a088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b600061424f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614e9b9092919063ffffffff16565b905080516000148061427057508080602001905181019061427091906159c3565b6112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016111ac565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261435a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611279565b50505050565b60608167ffffffffffffffff81111561437b5761437b615202565b6040519080825280602002602001820160405280156143a4578160200160208202803683370190505b50905060005b828110156143fb57835160140180519085528282815181106143ce576143ce615a7f565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016143aa565b5092915050565b60608167ffffffffffffffff81111561441d5761441d615202565b604051908082528060200260200182016040528015614446578160200160208202803683370190505b50905060005b828110156143fb578351600201805190855282828151811061447057614470615a7f565b61ffff9092166020928302919091019091015260010161444c565b805182516060919067ffffffffffffffff8111156144ab576144ab615202565b6040519080825280602002602001820160405280156144d4578160200160208202803683370190505b50915084826000815181106144eb576144eb615a7f565b60200260200101818152505060005b818110156146b657600085828151811061451657614516615a7f565b602002602001015190506000868360016145309190615a6c565b8151811061454057614540615a7f565b60200260200101519050600089848151811061455e5761455e615a7f565b60200260200101516127106145739190615927565b61ffff16905060008088868151811061458e5761458e615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156145e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146049190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561465f57905b828b0282612710020181848d02028161467a5761467a615959565b049a508a8861468a886001615a6c565b8151811061469a5761469a615a7f565b60209081029190910101525050600190930192506144fa915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361471e576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036148ad576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261493b8482614eb2565b61435a5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526149959085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611279565b61435a84826141ed565b8860ff16600103614acd578715614a58576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015614a3a57600080fd5b505af1158015614a4e573d6000803e3d6000fd5b5050505050614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614a21565b8860ff16600203614c0d578715614b98576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015614b6d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190614b929190615a53565b50614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614b4f565b8860ff16600303614dae578715614c8b576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614b4f565b8015614d05576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614b4f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015614d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b929190615a53565b8860ff16600403614e5e578715614df1576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614a21565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6060614eaa8484600085614f73565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614edc9190615bd3565b6000604051808303816000865af19150503d8060008114614f19576040519150601f19603f3d011682016040523d82523d6000602084013e614f1e565b606091505b5091509150818015614f48575080511580614f48575080806020019051810190614f4891906159c3565b8015614f6a575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b606082471015615005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016111ac565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161502e9190615bd3565b60006040518083038185875af1925050503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b50915091506150818783838761508c565b979650505050505050565b6060831561512257825160000361511b5773ffffffffffffffffffffffffffffffffffffffff85163b61511b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016111ac565b5081614eaa565b614eaa83838151156151375781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac9190615bef565b6000610140828403121561517e57600080fd5b50919050565b6000806040838503121561519757600080fd5b823567ffffffffffffffff808211156151af57600080fd5b6151bb8683870161516b565b935060208501359150808211156151d157600080fd5b508301604081860312156151e457600080fd5b809150509250929050565b61ffff811681146151ff57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561525557615255615202565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156152a2576152a2615202565b604052919050565b600067ffffffffffffffff8211156152c4576152c4615202565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261530157600080fd5b813561531461530f826152aa565b61525b565b81815284602083860101111561532957600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146151ff57600080fd5b60008060008060008060c0878903121561538157600080fd5b863561538c816151ef565b9550602087013567ffffffffffffffff808211156153a957600080fd5b6153b58a838b016152f0565b965060408901359550606089013591506153ce82615346565b9093506080880135925060a088013590808211156153eb57600080fd5b506153f889828a016152f0565b9150509295509295509295565b60006020828403121561541757600080fd5b813567ffffffffffffffff81111561542e57600080fd5b614eaa8482850161516b565b60006020828403121561544c57600080fd5b813561116781615346565b60006020828403121561546957600080fd5b8135611167816151ef565b65ffffffffffff811681146151ff57600080fd5b60006020828403121561549a57600080fd5b813561116781615474565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154da57600080fd5b83018035915067ffffffffffffffff8211156154f557600080fd5b60200191503681900382131561550a57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b80516155de81615346565b919050565b80516155de816151ef565b80516155de81615474565b60005b838110156156145781810151838201526020016155fc565b50506000910152565b600082601f83011261562e57600080fd5b815161563c61530f826152aa565b81815284602083860101111561565157600080fd5b614eaa8260208301602087016155f9565b60006020828403121561567457600080fd5b815167ffffffffffffffff8082111561568c57600080fd5b9083019061014082860312156156a157600080fd5b6156a9615231565b6156b2836155d3565b81526156c0602084016155e3565b60208201526156d1604084016155e3565b60408201526156e2606084016155d3565b60608201526156f3608084016155d3565b608082015261570460a084016155d3565b60a082015260c083015160c082015260e083015160e082015261010061572b8185016155ee565b90820152610120838101518381111561574357600080fd5b61574f8882870161561d565b918301919091525095945050505050565b600081518084526157788160208601602086016155f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526157d160208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516157e8604084018261ffff169052565b50604083015161ffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c083015160e083015260e08301516101008181850152808501519150506101206158938185018365ffffffffffff169052565b840151610140848101529050614eaa610160840182615760565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561113a5761113a6158ad565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615920576159206158ad565b5060010190565b61ffff8281168282160390808211156143fb576143fb6158ad565b808202811582820484141761113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156159d557600080fd5b8151801515811461116757600080fd5b80516dffffffffffffffffffffffffffff811681146155de57600080fd5b600080600060608486031215615a1857600080fd5b615a21846159e5565b9250615a2f602085016159e5565b9150604084015163ffffffff81168114615a4857600080fd5b809150509250925092565b600060208284031215615a6557600080fd5b5051919050565b8082018082111561113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215615ac157600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b0357615b036158ad565b5060000390565b600060208284031215615b1c57600080fd5b815161116781615346565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615b9a610180840182615760565b905082810360e0840152615bae8186615760565b9050828103610100840152615bc38185615760565b9c9b505050505050505050505050565b60008251615be58184602087016155f9565b9190910192915050565b602081526000611167602083018461576056fea26469706673582212202ce6a8f21a153c83c150806f9ce2e260656621d27c2de20b34fdaa1dbce5be3f64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json b/packages/hardhat/deployments/arbitrum/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json new file mode 100644 index 00000000..cf1aa121 --- /dev/null +++ b/packages/hardhat/deployments/arbitrum/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json @@ -0,0 +1,170 @@ +{ + "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" + }, + "@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * Perform the swap with tokens already moved to this contract\n */\n function curveExactInputSingleInternal(\n ExactInputSingleParams calldata params\n ) internal returns (uint256 amountOut) {\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 LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n useEth: params.tokenIn == address(0) || isToEth,\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function curveExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (params.tokenIn == address(0)) {\n revert PermitForEthToken();\n }\n\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 return curveExactInputSingleInternal(params);\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\n }\n\n return curveExactInputSingleInternal(params);\n }\n}\n" + }, + "contracts/facets/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract Stargate is IStargate {\n using SafeERC20 for IERC20;\n\n /**\n * Jump tokens with Stargate with input tokens already moved to this contract\n */\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.token,\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n // NOTE: This lookup is spending 319 gas\n IStargateRouter stargateRouter = IStargateRouter(\n LibWarp.state().stargateComposer.stargateRouter()\n );\n\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\n\n unchecked {\n stargateRouter.swap{value: msg.value}({\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\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\n }\n }\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable {\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.token,\n amount: 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 // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n uint160(params.amountIn),\n params.token\n );\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\n // Transfer tokens from the sender to this contract\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n address(0),\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n unchecked {\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\n _dstChainId: params.dstChainId,\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * NOTE: The tokens must already have been moved to the first pool\n */\n function uniswapV2LikeExactInputSingleInternal(\n ExactInputSingleParams memory params\n ) internal returns (uint256 amountOut) {\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : params.tokenIn,\n isToEth ? address(0) : params.tokenOut,\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\n }\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 the pool\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pool,\n (uint160)(params.amountIn),\n params.tokenIn\n );\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputInternal(\n ExactInputParams calldata params\n ) internal returns (uint256 amountOut) {\n LibWarp.State storage s = LibWarp.state();\n\n address[] memory tokens = params.tokens;\n uint256 poolLength = params.pools.length;\n bool isFromEth = tokens[0] == address(0);\n bool isToEth = tokens[poolLength] == address(0);\n\n if (isFromEth) {\n tokens[0] = address(s.weth);\n }\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : tokens[0],\n isToEth ? address(0) : tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\n } else {\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\n }\n\n return uniswapV2LikeExactInputInternal(params);\n }\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n // Permit tokens / set allowance\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n\n return uniswapV2LikeExactInputInternal(params);\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 {LibStarVault} from '../libraries/LibStarVault.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\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /**\n * NOTE: The tokens must already have been transferred to the pool\n */\n function uniswapV2ExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n address pair\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address tokenIn = params.tokenIn == address(0) ? address(s.weth) : params.tokenIn;\n address tokenOut = params.tokenOut == address(0) ? address(s.weth) : params.tokenOut;\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (tokenIn > 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 InsufficientOutputAmount();\n }\n\n bool zeroForOne = tokenIn < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.tokenOut == address(0)) {\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn == address(0) ? address(s.weth) : params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\n if (params.tokenIn == address(0)) {\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(address(s.weth)).safeTransfer(pair, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, pair, params.amountIn);\n }\n\n return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\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 return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n /**\n * NOTE: The tokens must already have been transferred to the first pool\n *\n * The path should be rewritten so address(0) is replaced by the WETH address\n */\n function uniswapV2ExactInputInternal(\n ExactInputParams calldata params,\n address[] memory path,\n address[] memory pairs,\n uint256[] memory amounts\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\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 = path[index] < path[indexPlusOne] ? true : false;\n address to = index < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH. 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(path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.path[0],\n params.path[pathLengthMinusOne],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[0] == address(0)) {\n // From ETH\n path[0] = address(s.weth);\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\n }\n\n if (params.path[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer WETH tokens to the first pool\n IERC20(path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n IERC20(path[0]).safeTransferFrom(msg.sender, pairs[0], params.amountIn);\n }\n\n return uniswapV2ExactInputInternal(params, path, pairs, amounts);\n }\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: 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 return uniswapV2ExactInputInternal(params, path, pairs, amounts);\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 if (callback.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n } else {\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\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 /**\n * NOTE: None of these arguments can be trusted\n */\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * KyperSwap V2 callback\n * NOTE: None of these arguments can be trusted\n */\n function swapCallback(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 {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n bool isFromEth = params.tokenIn == address(0);\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\n\n address tokenOut = params.tokenOut == address(0)\n ? address(LibWarp.state().weth)\n : params.tokenOut;\n\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\n\n bool zeroForOne = tokenIn < tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: tokenIn,\n amount: params.amountIn,\n usePermit: usePermit\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokenOut == address(0)) {\n // To ETH, unwrap WETH\n // TODO: This is read twice. Compare gas usage\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH, wrap it\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\n }\n\n function uniswapV3LikeExactInputInternal(\n ExactInputParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n uint256 poolLength = params.pools.length;\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\n address[] memory tokens = params.tokens;\n\n if (params.tokens[0] == address(0)) {\n tokens[0] = address(LibWarp.state().weth);\n }\n\n if (params.tokens[poolLength] == address(0)) {\n tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: payer,\n token: tokens[index],\n amount: amountOut,\n usePermit: usePermit\n })\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokens[poolLength] == address(0)) {\n // To ETH, unwrap\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.tokens[0],\n params.tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH, wrap it\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n }\n\n return uniswapV3LikeExactInputInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputInternal(params, 1);\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 {LibStarVault} from '../libraries/LibStarVault.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';\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\n bytes payload;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n address paramTokenIn;\n uint256 paramAmountIn;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint48 paramDeadline;\n uint256 amount;\n address payer;\n address token;\n /**\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\n */\n uint256 usePermit;\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 if (t.usePermit == 1) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\n }\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 if (t.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\n }\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(\n t.payer,\n params.pools[0],\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\n }\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({\n payer: t.payer,\n token: t.token,\n amount: t.amount,\n usePermit: t.usePermit\n })\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({\n payer: t.payer,\n token: tokenIn,\n amount: t.amount,\n usePermit: t.usePermit\n })\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\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 useEth: isFromEth || isToEth,\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 * Cross-chain callback from Stargate\n *\n * The tokens have already been received by this contract, `t.payer` is set to this contract\n * before `sgReceive` is called by the router.\n *\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\n * same message more than once.\n *\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\n * Stargate composer be compromised, an attacker can drain this contract.\n *\n * If the payload can not be decoded, tokens are left in this contract.\n * If execution runs out of gas, tokens are left in this contract.\n *\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\n * to the recipient.\n *\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\n */\n function sgReceive(\n uint16, // _srcChainId\n bytes memory _srcAddress,\n uint256, // _nonce\n address _token,\n uint256 amountLD,\n bytes memory payload\n ) external {\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\n revert InvalidSgReceiverSender();\n }\n\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\n // From https://ethereum.stackexchange.com/a/50528\n address srcAddress;\n\n assembly {\n srcAddress := mload(add(_srcAddress, 20))\n }\n\n if (srcAddress != address(this)) {\n // NOTE: This assumes that this contract is deployed at the same address on every chain\n revert InvalidSgReceiveSrcAddress();\n }\n\n Params memory params = abi.decode(payload, (Params));\n\n if (params.tokenIn == address(0)) {\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\n // otherwise because `_token` may be different on this chain\n _token = address(0);\n }\n\n try\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\n Params({\n partner: params.partner,\n feeBps: params.feeBps,\n slippageBps: params.slippageBps,\n recipient: params.recipient,\n tokenIn: _token,\n tokenOut: params.tokenOut,\n amountIn: amountLD,\n amountOut: params.amountOut,\n deadline: params.deadline,\n commands: params.commands\n })\n )\n {} catch {\n // Refund tokens to the recipient\n if (_token == address(0)) {\n payable(params.recipient).transfer(amountLD);\n } else {\n IERC20(_token).safeTransfer(params.recipient, amountLD);\n }\n }\n }\n\n /**\n * Jump to another chain using the Stargate bridge\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\n * in this function.\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 * - dstGasForCall (uint32)\n * - tokenOut (address) when `dstGasForCall` > 0\n * - amountOut (uint256) when `dstGasForCall` > 0\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n params.dstGasForCall = stream.readUint32();\n\n if (params.dstGasForCall > 0) {\n // NOTE: `amountIn` is left as zero\n Params memory destParams;\n destParams.partner = t.paramPartner;\n destParams.feeBps = t.paramFeeBps;\n destParams.slippageBps = t.paramSlippageBps;\n destParams.recipient = t.paramRecipient;\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\n // the same address as on this chain\n destParams.tokenIn = t.token;\n destParams.tokenOut = stream.readAddress();\n destParams.amountOut = stream.readUint256();\n destParams.deadline = t.paramDeadline;\n destParams.commands = stream.readBytes();\n params.payload = abi.encode(destParams);\n }\n\n if (t.token != t.paramTokenIn) {\n if (params.payload.length == 0) {\n // If the tokens are being delivered directly to the recipient without a second\n // WarpLink engage, the fee is charged on this chain\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\n // is never charged\n t.amount = LibStarVault.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n }\n\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n t.payer,\n address(this),\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\n\n // Update the payer to this contract\n // TODO: Is this value ever read?\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\n IERC20(t.token).forceApprove(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\n t.amount\n );\n }\n\n t.jumped = 1;\n\n // Swap on the composer if there is a payload, else the router\n IStargateRouter(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\n ).swap{\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\n }({\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\n // more on the other chain. It also assumes the tokens are of nearly equal value\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: params.dstGasForCall,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n // NOTE: This assumes the contract is deployed at the same address on every chain.\n // If this is not the case, a new param needs to be added with the next WarpLink address\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\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\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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable {\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.usePermit = 1;\n\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 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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\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(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy,\n bool use_eth\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\n// Kind 4, uint256s with no return value\n// Example v0.2.15, \"Pool for USDT/BTC/ETH or similar\"\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\ninterface ICurvePoolKind4 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\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/IStargateComposer.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\nimport {IStargateRouter} from './IStargateRouter.sol';\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateComposer is IStargateRouter {\n function stargateRouter() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/IStargateReceiver.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\n\ninterface IStargateReceiver {\n function sgReceive(\n uint16 _srcChainId, // the remote chainId sending the tokens\n bytes memory _srcAddress, // the remote Bridge address\n uint256 _nonce,\n address _token, // the token contract on the local chain\n uint256 amountLD, // the qty of local _token contract tokens\n bytes memory payload\n ) 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n /**\n * A function expecting a permit was used when the input token is ETH\n */\n error PermitForEthToken();\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 curveExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/ILibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibCurve {\n error UnhandledPoolKind();\n}\n" + }, + "contracts/interfaces/ILibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n}\n" + }, + "contracts/interfaces/ILibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n}\n" + }, + "contracts/interfaces/ILibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n}\n" + }, + "contracts/interfaces/IStargate.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\n\ninterface IStargate is ILibStarVault {\n error InsufficientEthValue();\n\n struct JumpTokenParams {\n address token;\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n struct JumpNativeParams {\n /**\n * The amount in is passed to distinguish the amount to bridge from the fee\n */\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable;\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Like is ILibStarVault, ILibWarp {\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 ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Router is ILibStarVault, ILibWarp {\n error EthTransferFailed();\n error ZeroAmountOut();\n error IncorrectEthValue();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\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 error InvalidSgReceiverSender();\n error InvalidSgReceiveSrcAddress();\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 calldata params) external payable;\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable;\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibCurve\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 bool useEth\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 if (useEth) {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\n } else {\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\n }\n } else if (kind == 4) {\n if (underlying) {\n revert UnhandledPoolKind();\n } else {\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * NOTE: Events and errors must be copied to ILibStarVault\n */\nlibrary LibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n\n struct State {\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 uint256 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n /**\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\n * removed to save gas.\n */\n unchecked {\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\n\n assembly {\n s.slot := storagePosition\n }\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 protocolFee\n ) internal {\n State storage s = state();\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit Fee(partner, token, partnerFee, protocolFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint256 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 feeProtocol = feeTotal - feePartner;\n\n if (feeProtocol > 0) {\n registerCollectedFee(partner, token, feePartner, feeProtocol);\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\n/**\n * NOTE: Events and errors must be copied to ILibUniV3Like\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 * Whether to use a permit transfer (0 or 1)\n */\n uint256 usePermit;\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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibWarp\n */\nlibrary LibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateComposer stargateComposer;\n }\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\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/avalanche/Curve.json b/packages/hardhat/deployments/avalanche/Curve.json index 8540c581..6f28babc 100644 --- a/packages/hardhat/deployments/avalanche/Curve.json +++ b/packages/hardhat/deployments/avalanche/Curve.json @@ -1,5 +1,5 @@ { - "address": "0x84Cd4555CeEA7B0A209232D2E47c316c08bAfDE8", + "address": "0x56880c7B8eE5c4CF8e362bfa4e493B4b6d3245d3", "abi": [ { "inputs": [], @@ -38,6 +38,11 @@ "name": "InsufficientOutputAmount", "type": "error" }, + { + "inputs": [], + "name": "PermitForEthToken", + "type": "error" + }, { "inputs": [], "name": "UnhandledPoolKind", @@ -116,6 +121,97 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "curveExactInputSingle", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -213,7 +309,7 @@ "type": "tuple" } ], - "name": "curveExactInputSingle", + "name": "curveExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -225,28 +321,28 @@ "type": "function" } ], - "transactionHash": "0x2b991d9e8ff1be3147082602c9118ab0a2e1183640c67843c1ccb50747ec4e6c", + "transactionHash": "0x702d86d97ac354f191a4e2b13c2d9a1405ffd4ecd880131722ccde80aa125e39", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x84Cd4555CeEA7B0A209232D2E47c316c08bAfDE8", - "transactionIndex": 4, - "gasUsed": "1361268", + "contractAddress": "0x56880c7B8eE5c4CF8e362bfa4e493B4b6d3245d3", + "transactionIndex": 6, + "gasUsed": "1468512", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x33a6140dfac7ae0797e21a5527d39dff14ea7ada319d5659ebd07bb253e0848d", - "transactionHash": "0x2b991d9e8ff1be3147082602c9118ab0a2e1183640c67843c1ccb50747ec4e6c", + "blockHash": "0xd7d71dc43d9fbc67e0137c06f5b996e2d0ef8bd58898700160220b48f67ea6fd", + "transactionHash": "0x702d86d97ac354f191a4e2b13c2d9a1405ffd4ecd880131722ccde80aa125e39", "logs": [], - "blockNumber": 36973147, - "cumulativeGasUsed": "1867292", + "blockNumber": 37398443, + "cumulativeGasUsed": "2345871", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 7, - "solcInputHash": "ebf955869df0dfecc3a0eb12547e8afc", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 useEth: params.tokenIn == address(0) || isToEth,\\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0x6d796fc46a41bd9fe76ae989d273f90aa0298f993f5c77cf481f5968fad21474\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\\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\":\"0x88d6dcf171951cf8e3f3488ef5d66a953614ae48926f9ace36d58b095bf9dc84\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506117d5806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b6100366100313660046113ad565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906114ed565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff9091169161066b565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b90890189611506565b6040518563ffffffff1660e01b815260040161026a9493929190611572565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b6103cc856101800151866101a001518760600151348961014001518a61016001518b6000015160008073ffffffffffffffffffffffffffffffffffffffff168e60e0015173ffffffffffffffffffffffffffffffffffffffff1614806103c757508a5b6107df565b60008261046d576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046891906114ed565b61046f565b475b905061047b8282611663565b935061048f86602001518760a00151610cdb565b8410156104c8576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ea8660c00151876101000151886080015161ffff16896020015188610d0b565b93508215610596576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610550576040519150601f19603f3d011682016040523d82523d6000602084013e610555565b606091505b5050905080610590576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506105ca565b6105ca86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610dc49092919063ffffffff16565b85610100015173ffffffffffffffffffffffffffffffffffffffff168660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f389600001518860405161065a929190918252602082015260400190565b60405180910390a450505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106f78482610e1f565b6107d95760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526107cf9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610ee0565b6107d98482610ee0565b50505050565b8860ff1660010361090d578715610898576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b5050505050610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610861565b8860ff16600203610a4d5787156109d8576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156109ad573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109d291906114ed565b50610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df0212490889060840161098f565b8860ff16600303610bee578715610acb576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b90889060840161098f565b8015610b45576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a40161098f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015610bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d291906114ed565b8860ff16600403610c9e578715610c31576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610861565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6000612710610cea8382611676565b610cf89061ffff1685611698565b610d0291906116af565b90505b92915050565b60006107d0841115610d52576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610d64575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610d9a5760646032840204610d9d565b60005b9050808303838214610db557610db58a8a8484610fef565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e1a9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161074d565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e49919061170e565b6000604051808303816000865af19150503d8060008114610e86576040519150601f19603f3d011682016040523d82523d6000602084013e610e8b565b606091505b5091509150818015610eb5575080511580610eb5575080806020019051810190610eb5919061172a565b8015610ed7575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166110b79092919063ffffffff16565b9050805160001480610f63575080806020019051810190610f63919061172a565b610e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d49565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60606110c684846000856110ce565b949350505050565b606082471015611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d49565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611189919061170e565b60006040518083038185875af1925050503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b50915091506111dc878383876111e7565b979650505050505050565b6060831561127d5782516000036112765773ffffffffffffffffffffffffffffffffffffffff85163b611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d49565b50816110c6565b6110c683838151156112925781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d49919061174e565b6040516101c0810167ffffffffffffffff81118282101715611311577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133b57600080fd5b919050565b803561ffff8116811461133b57600080fd5b803565ffffffffffff8116811461133b57600080fd5b803560ff8116811461133b57600080fd5b801515811461138757600080fd5b50565b803561133b81611379565b6000604082840312156113a757600080fd5b50919050565b6000808284036101e08112156113c257600080fd5b6101c0808212156113d257600080fd5b6113da6112c6565b915084358252602085013560208301526113f660408601611317565b604083015261140760608601611317565b606083015261141860808601611340565b608083015261142960a08601611340565b60a083015261143a60c08601611317565b60c083015261144b60e08601611317565b60e083015261010061145e818701611317565b90830152610120611470868201611352565b90830152610140611482868201611368565b90830152610160611494868201611368565b908301526101806114a6868201611368565b908301526101a06114b886820161138a565b9083015290925083013567ffffffffffffffff8111156114d757600080fd5b6114e385828601611395565b9150509250929050565b6000602082840312156114ff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261153b57600080fd5b83018035915067ffffffffffffffff82111561155657600080fd5b60200191503681900382131561156b57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d0557610d05611634565b61ffff82811682821603908082111561169157611691611634565b5092915050565b8082028115828204841417610d0557610d05611634565b6000826116e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156117055781810151838201526020016116ed565b50506000910152565b600082516117208184602087016116ea565b9190910192915050565b60006020828403121561173c57600080fd5b815161174781611379565b9392505050565b602081526000825180602084015261176d8160408501602087016116ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212204f164ad9f74d85efb515fab3ce059723b15ff2d1b51c1308c6989e26aff5f0c564736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b6100366100313660046113ad565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906114ed565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff9091169161066b565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b90890189611506565b6040518563ffffffff1660e01b815260040161026a9493929190611572565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b6103cc856101800151866101a001518760600151348961014001518a61016001518b6000015160008073ffffffffffffffffffffffffffffffffffffffff168e60e0015173ffffffffffffffffffffffffffffffffffffffff1614806103c757508a5b6107df565b60008261046d576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046891906114ed565b61046f565b475b905061047b8282611663565b935061048f86602001518760a00151610cdb565b8410156104c8576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ea8660c00151876101000151886080015161ffff16896020015188610d0b565b93508215610596576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610550576040519150601f19603f3d011682016040523d82523d6000602084013e610555565b606091505b5050905080610590576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506105ca565b6105ca86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610dc49092919063ffffffff16565b85610100015173ffffffffffffffffffffffffffffffffffffffff168660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f389600001518860405161065a929190918252602082015260400190565b60405180910390a450505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106f78482610e1f565b6107d95760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526107cf9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610ee0565b6107d98482610ee0565b50505050565b8860ff1660010361090d578715610898576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b5050505050610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610861565b8860ff16600203610a4d5787156109d8576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156109ad573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109d291906114ed565b50610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df0212490889060840161098f565b8860ff16600303610bee578715610acb576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b90889060840161098f565b8015610b45576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a40161098f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015610bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d291906114ed565b8860ff16600403610c9e578715610c31576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610861565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6000612710610cea8382611676565b610cf89061ffff1685611698565b610d0291906116af565b90505b92915050565b60006107d0841115610d52576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610d64575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610d9a5760646032840204610d9d565b60005b9050808303838214610db557610db58a8a8484610fef565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e1a9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161074d565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e49919061170e565b6000604051808303816000865af19150503d8060008114610e86576040519150601f19603f3d011682016040523d82523d6000602084013e610e8b565b606091505b5091509150818015610eb5575080511580610eb5575080806020019051810190610eb5919061172a565b8015610ed7575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166110b79092919063ffffffff16565b9050805160001480610f63575080806020019051810190610f63919061172a565b610e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d49565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60606110c684846000856110ce565b949350505050565b606082471015611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d49565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611189919061170e565b60006040518083038185875af1925050503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b50915091506111dc878383876111e7565b979650505050505050565b6060831561127d5782516000036112765773ffffffffffffffffffffffffffffffffffffffff85163b611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d49565b50816110c6565b6110c683838151156112925781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d49919061174e565b6040516101c0810167ffffffffffffffff81118282101715611311577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133b57600080fd5b919050565b803561ffff8116811461133b57600080fd5b803565ffffffffffff8116811461133b57600080fd5b803560ff8116811461133b57600080fd5b801515811461138757600080fd5b50565b803561133b81611379565b6000604082840312156113a757600080fd5b50919050565b6000808284036101e08112156113c257600080fd5b6101c0808212156113d257600080fd5b6113da6112c6565b915084358252602085013560208301526113f660408601611317565b604083015261140760608601611317565b606083015261141860808601611340565b608083015261142960a08601611340565b60a083015261143a60c08601611317565b60c083015261144b60e08601611317565b60e083015261010061145e818701611317565b90830152610120611470868201611352565b90830152610140611482868201611368565b90830152610160611494868201611368565b908301526101806114a6868201611368565b908301526101a06114b886820161138a565b9083015290925083013567ffffffffffffffff8111156114d757600080fd5b6114e385828601611395565b9150509250929050565b6000602082840312156114ff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261153b57600080fd5b83018035915067ffffffffffffffff82111561155657600080fd5b60200191503681900382131561156b57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d0557610d05611634565b61ffff82811682821603908082111561169157611691611634565b5092915050565b8082028115828204841417610d0557610d05611634565b6000826116e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156117055781810151838201526020016116ed565b50506000910152565b600082516117208184602087016116ea565b9190910192915050565b60006020828403121561173c57600080fd5b815161174781611379565b9392505050565b602081526000825180602084015261176d8160408501602087016116ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212204f164ad9f74d85efb515fab3ce059723b15ff2d1b51c1308c6989e26aff5f0c564736f6c63430008130033", + "numDeployments": 8, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermitForEthToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"name\":\"curveExactInputSingle\",\"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\":\"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\":\"curveExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}],\"PermitForEthToken()\":[{\"notice\":\"A function expecting a permit was used when the input token is ETH\"}]},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\\n * Perform the swap with tokens already moved to this contract\\n */\\n function curveExactInputSingleInternal(\\n ExactInputSingleParams calldata params\\n ) internal returns (uint256 amountOut) {\\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 LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n useEth: params.tokenIn == address(0) || isToEth,\\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function curveExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (params.tokenIn == address(0)) {\\n revert PermitForEthToken();\\n }\\n\\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 return curveExactInputSingleInternal(params);\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\\n }\\n\\n return curveExactInputSingleInternal(params);\\n }\\n}\\n\",\"keccak256\":\"0x14d74eb8ac6efa00532e5de577c6b6ca66866e6991a220986ca7733d920de561\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n /**\\n * A function expecting a permit was used when the input token is ETH\\n */\\n error PermitForEthToken();\\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 curveExactInputSinglePermit(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xd034586f038b6ea01e6ce9d6497d203ef8cc5d221884f1a6f608ce08bae51904\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506119c8806100206000396000f3fe6080604052600436106100295760003560e01c806356bf88f01461002e578063aef417b114610053575b600080fd5b61004161003c366004611598565b610066565b60405190815260200160405180910390f35b6100416100613660046115f0565b610348565b60008061007a610100850160e0860161160d565b73ffffffffffffffffffffffffffffffffffffffff16036100c7576040517f53e40ce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a6100da608085016060860161160d565b84356100ed610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff169190610430565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925273ffffffffffffffffffffffffffffffffffffffff90921691632b67b57091339190819060608201908190610174906101008c01908c0161160d565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016101ab6101408b016101208c0161164a565b65ffffffffffff908116825289351660209182015290825230908201526040016101dd61014089016101208a0161164a565b65ffffffffffff1690526101f46020870187611672565b6040518563ffffffff1660e01b815260040161021394939291906116de565b600060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505061026c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333086356102a0610100890160e08a0161160d565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561031e57600080fd5b505af1158015610332573d6000803e3d6000fd5b5050505061033f836105a4565b90505b92915050565b600061035c6101408301610120840161164a565b65ffffffffffff1642111561039d576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103b0610100840160e0850161160d565b73ffffffffffffffffffffffffffffffffffffffff1614610427576103f16103de608084016060850161160d565b83356100ed610100860160e0870161160d565b61042733308435610409610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff16929190610a43565b610342826105a4565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526104bc8482610aa1565b61059e5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526105949085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610b62565b61059e8482610b62565b50505050565b600080806105ba6101208501610100860161160d565b73ffffffffffffffffffffffffffffffffffffffff16149050600081610681576105ec6101208501610100860161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c91906117a0565b610683565b475b905061073661069a6101a0860161018087016117b9565b6106ac6101c087016101a088016117ed565b6106bc608088016060890161160d565b346106cf6101608a016101408b016117b9565b6106e16101808b016101608c016117b9565b8a6000013560008073ffffffffffffffffffffffffffffffffffffffff168d60e0016020810190610712919061160d565b73ffffffffffffffffffffffffffffffffffffffff16148061073157508a5b610c7b565b6000826107e45761074f6101208601610100870161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df91906117a0565b6107e6565b475b90506107f28282611839565b9350610811602086013561080c60c0880160a0890161184c565b611177565b84101561084a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088e61085d60e0870160c0880161160d565b61086f6101208801610100890161160d565b61087f60a0890160808a0161184c565b61ffff1688602001358861119e565b935082156109455760006108a8606087016040880161160d565b73ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146108ff576040519150601f19603f3d011682016040523d82523d6000602084013e610904565b606091505b505090508061093f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610988565b610988610958606087016040880161160d565b8561096b61012089016101008a0161160d565b73ffffffffffffffffffffffffffffffffffffffff169190611252565b61099a6101208601610100870161160d565b73ffffffffffffffffffffffffffffffffffffffff166109c1610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff166109e760e0880160c0890161160d565b60408051893581526020810189905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261059e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610512565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610acb9190611894565b6000604051808303816000865af19150503d8060008114610b08576040519150601f19603f3d011682016040523d82523d6000602084013e610b0d565b606091505b5091509150818015610b37575080511580610b37575080806020019051810190610b3791906118b0565b8015610b59575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610bc4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112a89092919063ffffffff16565b9050805160001480610be5575080806020019051810190610be591906118b0565b610c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b8860ff16600103610da9578715610d34576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015610d1657600080fd5b505af1158015610d2a573d6000803e3d6000fd5b505050505061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610cfd565b8860ff16600203610ee9578715610e74576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015610e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b5061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610e2b565b8860ff1660030361108a578715610f67576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401610e2b565b8015610fe1576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401610e2b565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015611066573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b8860ff1660040361113a5787156110cd576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610cfd565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600061271061118683826118cd565b6111949061ffff16856118ef565b61033f9190611906565b60006107d08411156111e0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d06004820152602401610c6d565b600082848111156111f2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611228576064603284020461122b565b60005b9050808303838214611243576112438a8a84846112bf565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c769084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610512565b60606112b78484600085611387565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606082471015611419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c6d565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516114429190611894565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b5091509150611495878383876114a0565b979650505050505050565b6060831561153657825160000361152f5773ffffffffffffffffffffffffffffffffffffffff85163b61152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c6d565b50816112b7565b6112b7838381511561154b5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9190611941565b60006101c0828403121561159257600080fd5b50919050565b6000806101e083850312156115ac57600080fd5b6115b6848461157f565b91506101c083013567ffffffffffffffff8111156115d357600080fd5b8301604081860312156115e557600080fd5b809150509250929050565b60006101c0828403121561160357600080fd5b61033f838361157f565b60006020828403121561161f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461164357600080fd5b9392505050565b60006020828403121561165c57600080fd5b813565ffffffffffff8116811461164357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126116a757600080fd5b83018035915067ffffffffffffffff8211156116c257600080fd5b6020019150368190038213156116d757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156117b257600080fd5b5051919050565b6000602082840312156117cb57600080fd5b813560ff8116811461164357600080fd5b80151581146117ea57600080fd5b50565b6000602082840312156117ff57600080fd5b8135611643816117dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156103425761034261180a565b60006020828403121561185e57600080fd5b813561ffff8116811461164357600080fd5b60005b8381101561188b578181015183820152602001611873565b50506000910152565b600082516118a6818460208701611870565b9190910192915050565b6000602082840312156118c257600080fd5b8151611643816117dc565b61ffff8281168282160390808211156118e8576118e861180a565b5092915050565b80820281158282048414176103425761034261180a565b60008261193c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6020815260008251806020840152611960816040850160208701611870565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202b55d2f11aa7f1395a3e9c79ad5594ecdb6d8158214c767aed2d3da3a5500d1264736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c806356bf88f01461002e578063aef417b114610053575b600080fd5b61004161003c366004611598565b610066565b60405190815260200160405180910390f35b6100416100613660046115f0565b610348565b60008061007a610100850160e0860161160d565b73ffffffffffffffffffffffffffffffffffffffff16036100c7576040517f53e40ce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a6100da608085016060860161160d565b84356100ed610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff169190610430565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925273ffffffffffffffffffffffffffffffffffffffff90921691632b67b57091339190819060608201908190610174906101008c01908c0161160d565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016101ab6101408b016101208c0161164a565b65ffffffffffff908116825289351660209182015290825230908201526040016101dd61014089016101208a0161164a565b65ffffffffffff1690526101f46020870187611672565b6040518563ffffffff1660e01b815260040161021394939291906116de565b600060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505061026c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333086356102a0610100890160e08a0161160d565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561031e57600080fd5b505af1158015610332573d6000803e3d6000fd5b5050505061033f836105a4565b90505b92915050565b600061035c6101408301610120840161164a565b65ffffffffffff1642111561039d576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103b0610100840160e0850161160d565b73ffffffffffffffffffffffffffffffffffffffff1614610427576103f16103de608084016060850161160d565b83356100ed610100860160e0870161160d565b61042733308435610409610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff16929190610a43565b610342826105a4565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526104bc8482610aa1565b61059e5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526105949085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610b62565b61059e8482610b62565b50505050565b600080806105ba6101208501610100860161160d565b73ffffffffffffffffffffffffffffffffffffffff16149050600081610681576105ec6101208501610100860161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c91906117a0565b610683565b475b905061073661069a6101a0860161018087016117b9565b6106ac6101c087016101a088016117ed565b6106bc608088016060890161160d565b346106cf6101608a016101408b016117b9565b6106e16101808b016101608c016117b9565b8a6000013560008073ffffffffffffffffffffffffffffffffffffffff168d60e0016020810190610712919061160d565b73ffffffffffffffffffffffffffffffffffffffff16148061073157508a5b610c7b565b6000826107e45761074f6101208601610100870161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df91906117a0565b6107e6565b475b90506107f28282611839565b9350610811602086013561080c60c0880160a0890161184c565b611177565b84101561084a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088e61085d60e0870160c0880161160d565b61086f6101208801610100890161160d565b61087f60a0890160808a0161184c565b61ffff1688602001358861119e565b935082156109455760006108a8606087016040880161160d565b73ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146108ff576040519150601f19603f3d011682016040523d82523d6000602084013e610904565b606091505b505090508061093f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610988565b610988610958606087016040880161160d565b8561096b61012089016101008a0161160d565b73ffffffffffffffffffffffffffffffffffffffff169190611252565b61099a6101208601610100870161160d565b73ffffffffffffffffffffffffffffffffffffffff166109c1610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff166109e760e0880160c0890161160d565b60408051893581526020810189905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261059e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610512565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610acb9190611894565b6000604051808303816000865af19150503d8060008114610b08576040519150601f19603f3d011682016040523d82523d6000602084013e610b0d565b606091505b5091509150818015610b37575080511580610b37575080806020019051810190610b3791906118b0565b8015610b59575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610bc4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112a89092919063ffffffff16565b9050805160001480610be5575080806020019051810190610be591906118b0565b610c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b8860ff16600103610da9578715610d34576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015610d1657600080fd5b505af1158015610d2a573d6000803e3d6000fd5b505050505061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610cfd565b8860ff16600203610ee9578715610e74576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015610e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b5061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610e2b565b8860ff1660030361108a578715610f67576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401610e2b565b8015610fe1576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401610e2b565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015611066573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b8860ff1660040361113a5787156110cd576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610cfd565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600061271061118683826118cd565b6111949061ffff16856118ef565b61033f9190611906565b60006107d08411156111e0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d06004820152602401610c6d565b600082848111156111f2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611228576064603284020461122b565b60005b9050808303838214611243576112438a8a84846112bf565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c769084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610512565b60606112b78484600085611387565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606082471015611419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c6d565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516114429190611894565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b5091509150611495878383876114a0565b979650505050505050565b6060831561153657825160000361152f5773ffffffffffffffffffffffffffffffffffffffff85163b61152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c6d565b50816112b7565b6112b7838381511561154b5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9190611941565b60006101c0828403121561159257600080fd5b50919050565b6000806101e083850312156115ac57600080fd5b6115b6848461157f565b91506101c083013567ffffffffffffffff8111156115d357600080fd5b8301604081860312156115e557600080fd5b809150509250929050565b60006101c0828403121561160357600080fd5b61033f838361157f565b60006020828403121561161f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461164357600080fd5b9392505050565b60006020828403121561165c57600080fd5b813565ffffffffffff8116811461164357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126116a757600080fd5b83018035915067ffffffffffffffff8211156116c257600080fd5b6020019150368190038213156116d757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156117b257600080fd5b5051919050565b6000602082840312156117cb57600080fd5b813560ff8116811461164357600080fd5b80151581146117ea57600080fd5b50565b6000602082840312156117ff57600080fd5b8135611643816117dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156103425761034261180a565b60006020828403121561185e57600080fd5b813561ffff8116811461164357600080fd5b60005b8381101561188b578181015183820152602001611873565b50506000910152565b600082516118a6818460208701611870565b9190910192915050565b6000602082840312156118c257600080fd5b8151611643816117dc565b61ffff8281168282160390808211156118e8576118e861180a565b5092915050565b80820281158282048414176103425761034261180a565b60008261193c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6020815260008251806020840152611960816040850160208701611870565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202b55d2f11aa7f1395a3e9c79ad5594ecdb6d8158214c767aed2d3da3a5500d1264736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, @@ -261,6 +357,11 @@ { "notice": "The swap fee is over the maximum allowed" } + ], + "PermitForEthToken()": [ + { + "notice": "A function expecting a permit was used when the input token is ETH" + } ] }, "kind": "user", diff --git a/packages/hardhat/deployments/avalanche/Stargate.json b/packages/hardhat/deployments/avalanche/Stargate.json index 5ab476d5..14be8a8e 100644 --- a/packages/hardhat/deployments/avalanche/Stargate.json +++ b/packages/hardhat/deployments/avalanche/Stargate.json @@ -1,5 +1,5 @@ { - "address": "0xBc3DF9Aa6223128F517fDb3C93d51B1a28F0f96A", + "address": "0x352AfE52B0972d67148C01690cB90281fBF6bC35", "abi": [ { "inputs": [ @@ -124,6 +124,76 @@ "stateMutability": "payable", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint160", + "name": "amountIn", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "amountOutExpected", + "type": "uint160" + }, + { + "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": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "srcPoolId", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "dstPoolId", + "type": "uint8" + } + ], + "internalType": "struct IStargate.JumpTokenParams", + "name": "params", + "type": "tuple" + } + ], + "name": "stargateJumpToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -206,34 +276,34 @@ "type": "tuple" } ], - "name": "stargateJumpToken", + "name": "stargateJumpTokenPermit", "outputs": [], "stateMutability": "payable", "type": "function" } ], - "transactionHash": "0x2478d5ce660ba450c12f6d8d4816dccc36b591a97e0d6f30a32f3a440e6b3a15", + "transactionHash": "0x218e8a9aa6ac6981de5c891b631214af86077942987bafb41beac96675996db7", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xBc3DF9Aa6223128F517fDb3C93d51B1a28F0f96A", - "transactionIndex": 4, - "gasUsed": "1184682", + "contractAddress": "0x352AfE52B0972d67148C01690cB90281fBF6bC35", + "transactionIndex": 7, + "gasUsed": "1254228", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x81cae93a839d423e82c6b0edd52634d62281c0352af3ae154fca7d101e06410f", - "transactionHash": "0x2478d5ce660ba450c12f6d8d4816dccc36b591a97e0d6f30a32f3a440e6b3a15", + "blockHash": "0xd1a620372e413ff5a8d0ce1ccc79d354e6ed2ed8a8a93b7f507633610d8d7971", + "transactionHash": "0x218e8a9aa6ac6981de5c891b631214af86077942987bafb41beac96675996db7", "logs": [], - "blockNumber": 36642966, - "cumulativeGasUsed": "1686624", + "blockNumber": 37398454, + "cumulativeGasUsed": "2369090", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpNativeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"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\":\"stargateJumpToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Stargate.sol\":\"Stargate\"},\"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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract Stargate is IStargate {\\n using SafeERC20 for IERC20;\\n\\n function stargateJumpToken(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.token,\\n amount: 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 // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n uint160(params.amountIn),\\n params.token\\n );\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.token,\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n // NOTE: This lookup is spending 319 gas\\n IStargateRouter stargateRouter = IStargateRouter(\\n LibWarp.state().stargateComposer.stargateRouter()\\n );\\n\\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\\n\\n unchecked {\\n stargateRouter.swap{value: msg.value}({\\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\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n address(0),\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n unchecked {\\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n}\\n\",\"keccak256\":\"0x384ff4fd006f55fd52c6532724722c9d8709db7760e8296c8a9447a19bd148f1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/IStargate.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\n\\ninterface IStargate is ILibStarVault {\\n error InsufficientEthValue();\\n\\n struct JumpTokenParams {\\n address token;\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n struct JumpNativeParams {\\n /**\\n * The amount in is passed to distinguish the amount to bridge from the fee\\n */\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n function stargateJumpToken(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\\n}\\n\",\"keccak256\":\"0x4464ecac16a3c449c8f7983ac21ba54a44ac02194baa590c480b6ffc1cddd478\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b5061148c806100206000396000f3fe6080604052600436106100295760003560e01c806329859a061461002e578063c2bee2af14610043575b600080fd5b61004161003c366004610fca565b610056565b005b610041610051366004611029565b610618565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100b760208a018a611067565b73ffffffffffffffffffffffffffffffffffffffff1681526020018860200160208101906100e59190611067565b73ffffffffffffffffffffffffffffffffffffffff16815260200161011060e08a0160c08b0161108b565b65ffffffffffff9081168252883516602091820152908252309082015260400161014060e0880160c0890161108b565b65ffffffffffff16905261015760208601866110b3565b6040518563ffffffff1660e01b8152600401610176949392919061111f565b600060405180830381600087803b15801561019057600080fd5b505af11580156101a4573d6000803e3d6000fd5b505050506101cf7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633306102006040870160208801611067565b61020d6020880188611067565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561028b57600080fd5b505af115801561029f573d6000803e3d6000fd5b50505050600061032d8360e00160208101906102bb9190611067565b6102c86020860186611067565b6102d860c0870160a088016111e1565b61ffff166102ec6040880160208901611067565b73ffffffffffffffffffffffffffffffffffffffff166103126040890160208a01611067565b73ffffffffffffffffffffffffffffffffffffffff16610905565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190611205565b905061041581836103f86020880188611067565b73ffffffffffffffffffffffffffffffffffffffff1691906109be565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc34610444610120880161010089016111e1565b61045661014089016101208a01611222565b6104686101608a016101408b01611222565b33888061047b60408e0160208f01611067565b73ffffffffffffffffffffffffffffffffffffffff16036104a260608e0160408f01611067565b73ffffffffffffffffffffffffffffffffffffffff16116104c4576000610534565b6105348a8d60200160208101906104db9190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d60400160208101906105059190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d608001602081019061052f91906111e1565b610aee565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508d60600160208101906105739190611067565b6040516020016105ae919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016105e09897969594939291906112b3565b6000604051808303818588803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050505050505050565b6106256020820182611067565b73ffffffffffffffffffffffffffffffffffffffff16341015610674576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106cf61068960e0840160c08501611067565b600061069b60a08601608087016111e1565b61ffff166106ac6020870187611067565b73ffffffffffffffffffffffffffffffffffffffff166103126020880188611067565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261071d6020860186611067565b73ffffffffffffffffffffffffffffffffffffffff16033403610747610100860160e087016111e1565b61075961012087016101008801611222565b61076b61014088016101208901611222565b33878061077b60208c018c611067565b73ffffffffffffffffffffffffffffffffffffffff16036107a260408c0160208d01611067565b73ffffffffffffffffffffffffffffffffffffffff16116107c4576000610823565b610823896107d560208d018d611067565b73ffffffffffffffffffffffffffffffffffffffff16036107fc60408d0160208e01611067565b73ffffffffffffffffffffffffffffffffffffffff160361052f60808d0160608e016111e1565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b60400160208101906108629190611067565b60405160200161089d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016108cf9897969594939291906112b3565b6000604051808303818588803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b50505050505050565b60006107d084111561094c576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561095e575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109945760646032840204610997565b60005b90508083038382146109af576109af8a8a8484610b1e565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610a4a8482610be6565b610ae8576040805173ffffffffffffffffffffffffffffffffffffffff8516602482015260006044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610ade908590610ca7565b610ae88482610ca7565b50505050565b6000612710610afd8382611391565b610b0b9061ffff16856113b3565b610b1591906113ca565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c109190611405565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611421565b8015610c9e575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610dbb9092919063ffffffff16565b9050805160001480610d2a575080806020019051810190610d2a9190611421565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610943565b505050565b6060610dca8484600085610dd2565b949350505050565b606082471015610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610943565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610e8d9190611405565b60006040518083038185875af1925050503d8060008114610eca576040519150601f19603f3d011682016040523d82523d6000602084013e610ecf565b606091505b5091509150610ee087838387610eeb565b979650505050505050565b60608315610f81578251600003610f7a5773ffffffffffffffffffffffffffffffffffffffff85163b610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b5081610dca565b610dca8383815115610f965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109439190611443565b600080828403610180811215610fdf57600080fd5b61016080821215610fef57600080fd5b849350830135905067ffffffffffffffff81111561100c57600080fd5b83016040818603121561101e57600080fd5b809150509250929050565b6000610140828403121561103c57600080fd5b50919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461106457600080fd5b50565b60006020828403121561107957600080fd5b813561108481611042565b9392505050565b60006020828403121561109d57600080fd5b813565ffffffffffff8116811461108457600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110e857600080fd5b83018035915067ffffffffffffffff82111561110357600080fd5b60200191503681900382131561111857600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156111f357600080fd5b813561ffff8116811461108457600080fd5b60006020828403121561121757600080fd5b815161108481611042565b60006020828403121561123457600080fd5b813560ff8116811461108457600080fd5b60005b83811015611260578181015183820152602001611248565b50506000910152565b60008151808452611281816020860160208601611245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c08401528451818401525060208401516101408301526040840151606061016084015261132c610180840182611269565b905082810360e08401526113408185611269565b838103610100850152600081529050602081019b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156113ac576113ac611362565b5092915050565b8082028115828204841417610b1857610b18611362565b600082611400577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251611417818460208701611245565b9190910192915050565b60006020828403121561143357600080fd5b8151801515811461108457600080fd5b602081526000610b15602083018461126956fea2646970667358221220fd4949e43a56ae6a92fdbb921568c2bc2a7013da24304d0b873ce9c5e7515c0264736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806329859a061461002e578063c2bee2af14610043575b600080fd5b61004161003c366004610fca565b610056565b005b610041610051366004611029565b610618565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100b760208a018a611067565b73ffffffffffffffffffffffffffffffffffffffff1681526020018860200160208101906100e59190611067565b73ffffffffffffffffffffffffffffffffffffffff16815260200161011060e08a0160c08b0161108b565b65ffffffffffff9081168252883516602091820152908252309082015260400161014060e0880160c0890161108b565b65ffffffffffff16905261015760208601866110b3565b6040518563ffffffff1660e01b8152600401610176949392919061111f565b600060405180830381600087803b15801561019057600080fd5b505af11580156101a4573d6000803e3d6000fd5b505050506101cf7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633306102006040870160208801611067565b61020d6020880188611067565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561028b57600080fd5b505af115801561029f573d6000803e3d6000fd5b50505050600061032d8360e00160208101906102bb9190611067565b6102c86020860186611067565b6102d860c0870160a088016111e1565b61ffff166102ec6040880160208901611067565b73ffffffffffffffffffffffffffffffffffffffff166103126040890160208a01611067565b73ffffffffffffffffffffffffffffffffffffffff16610905565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190611205565b905061041581836103f86020880188611067565b73ffffffffffffffffffffffffffffffffffffffff1691906109be565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc34610444610120880161010089016111e1565b61045661014089016101208a01611222565b6104686101608a016101408b01611222565b33888061047b60408e0160208f01611067565b73ffffffffffffffffffffffffffffffffffffffff16036104a260608e0160408f01611067565b73ffffffffffffffffffffffffffffffffffffffff16116104c4576000610534565b6105348a8d60200160208101906104db9190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d60400160208101906105059190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d608001602081019061052f91906111e1565b610aee565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508d60600160208101906105739190611067565b6040516020016105ae919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016105e09897969594939291906112b3565b6000604051808303818588803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050505050505050565b6106256020820182611067565b73ffffffffffffffffffffffffffffffffffffffff16341015610674576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106cf61068960e0840160c08501611067565b600061069b60a08601608087016111e1565b61ffff166106ac6020870187611067565b73ffffffffffffffffffffffffffffffffffffffff166103126020880188611067565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261071d6020860186611067565b73ffffffffffffffffffffffffffffffffffffffff16033403610747610100860160e087016111e1565b61075961012087016101008801611222565b61076b61014088016101208901611222565b33878061077b60208c018c611067565b73ffffffffffffffffffffffffffffffffffffffff16036107a260408c0160208d01611067565b73ffffffffffffffffffffffffffffffffffffffff16116107c4576000610823565b610823896107d560208d018d611067565b73ffffffffffffffffffffffffffffffffffffffff16036107fc60408d0160208e01611067565b73ffffffffffffffffffffffffffffffffffffffff160361052f60808d0160608e016111e1565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b60400160208101906108629190611067565b60405160200161089d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016108cf9897969594939291906112b3565b6000604051808303818588803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b50505050505050565b60006107d084111561094c576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561095e575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109945760646032840204610997565b60005b90508083038382146109af576109af8a8a8484610b1e565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610a4a8482610be6565b610ae8576040805173ffffffffffffffffffffffffffffffffffffffff8516602482015260006044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610ade908590610ca7565b610ae88482610ca7565b50505050565b6000612710610afd8382611391565b610b0b9061ffff16856113b3565b610b1591906113ca565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c109190611405565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611421565b8015610c9e575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610dbb9092919063ffffffff16565b9050805160001480610d2a575080806020019051810190610d2a9190611421565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610943565b505050565b6060610dca8484600085610dd2565b949350505050565b606082471015610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610943565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610e8d9190611405565b60006040518083038185875af1925050503d8060008114610eca576040519150601f19603f3d011682016040523d82523d6000602084013e610ecf565b606091505b5091509150610ee087838387610eeb565b979650505050505050565b60608315610f81578251600003610f7a5773ffffffffffffffffffffffffffffffffffffffff85163b610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b5081610dca565b610dca8383815115610f965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109439190611443565b600080828403610180811215610fdf57600080fd5b61016080821215610fef57600080fd5b849350830135905067ffffffffffffffff81111561100c57600080fd5b83016040818603121561101e57600080fd5b809150509250929050565b6000610140828403121561103c57600080fd5b50919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461106457600080fd5b50565b60006020828403121561107957600080fd5b813561108481611042565b9392505050565b60006020828403121561109d57600080fd5b813565ffffffffffff8116811461108457600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110e857600080fd5b83018035915067ffffffffffffffff82111561110357600080fd5b60200191503681900382131561111857600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156111f357600080fd5b813561ffff8116811461108457600080fd5b60006020828403121561121757600080fd5b815161108481611042565b60006020828403121561123457600080fd5b813560ff8116811461108457600080fd5b60005b83811015611260578181015183820152602001611248565b50506000910152565b60008151808452611281816020860160208601611245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c08401528451818401525060208401516101408301526040840151606061016084015261132c610180840182611269565b905082810360e08401526113408185611269565b838103610100850152600081529050602081019b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156113ac576113ac611362565b5092915050565b8082028115828204841417610b1857610b18611362565b600082611400577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251611417818460208701611245565b9190910192915050565b60006020828403121561143357600080fd5b8151801515811461108457600080fd5b602081526000610b15602083018461126956fea2646970667358221220fd4949e43a56ae6a92fdbb921568c2bc2a7013da24304d0b873ce9c5e7515c0264736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpNativeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"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\":\"stargateJumpTokenPermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Stargate.sol\":\"Stargate\"},\"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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract Stargate is IStargate {\\n using SafeERC20 for IERC20;\\n\\n /**\\n * Jump tokens with Stargate with input tokens already moved to this contract\\n */\\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.token,\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n // NOTE: This lookup is spending 319 gas\\n IStargateRouter stargateRouter = IStargateRouter(\\n LibWarp.state().stargateComposer.stargateRouter()\\n );\\n\\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\\n\\n unchecked {\\n stargateRouter.swap{value: msg.value}({\\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\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n\\n function stargateJumpTokenPermit(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.token,\\n amount: 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 // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n uint160(params.amountIn),\\n params.token\\n );\\n\\n stargateJumpTokenInternal(params);\\n }\\n\\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\\n // Transfer tokens from the sender to this contract\\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\\n\\n stargateJumpTokenInternal(params);\\n }\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n address(0),\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n unchecked {\\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6abe4954877eed5b5a9c473441ac11e6f505d6cedc5c1d9489960227c5fb6f84\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/IStargate.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\n\\ninterface IStargate is ILibStarVault {\\n error InsufficientEthValue();\\n\\n struct JumpTokenParams {\\n address token;\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n struct JumpNativeParams {\\n /**\\n * The amount in is passed to distinguish the amount to bridge from the fee\\n */\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\\n\\n function stargateJumpTokenPermit(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\\n}\\n\",\"keccak256\":\"0xb35bd721e5ab9f7cd120a61bdafd807dcebd1cf71f5189662697f47a1f10986c\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506115d1806100206000396000f3fe6080604052600436106100345760003560e01c80638be9f27914610039578063ba2466d41461004e578063c2bee2af14610061575b600080fd5b61004c610047366004611102565b610074565b005b61004c61005c36600461115a565b6102ce565b61004c61006f366004611177565b610330565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100d560208a018a6111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200188602001602081019061010391906111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200161012e60e08a0160c08b016111d0565b65ffffffffffff9081168252883516602091820152908252309082015260400161015e60e0880160c089016111d0565b65ffffffffffff16905261017560208601866111f8565b6040518563ffffffff1660e01b81526004016101949493929190611264565b600060405180830381600087803b1580156101ae57600080fd5b505af11580156101c2573d6000803e3d6000fd5b505050506101ed7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333061021e60408701602088016111ac565b61022b60208801886111ac565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102a957600080fd5b505af11580156102bd573d6000803e3d6000fd5b505050506102ca8261063d565b5050565b61032433306102e360408501602086016111ac565b73ffffffffffffffffffffffffffffffffffffffff1661030660208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff16929190610986565b61032d8161063d565b50565b61033d60208201826111ac565b73ffffffffffffffffffffffffffffffffffffffff1634101561038c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104026103a160e0840160c085016111ac565b60006103b360a0860160808701611326565b61ffff166103c460208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760208801886111ac565b73ffffffffffffffffffffffffffffffffffffffff16610a68565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261045060208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff1603340361047a610100860160e08701611326565b61048c6101208701610100880161134a565b61049e6101408801610120890161134a565b3387806104ae60208c018c6111ac565b73ffffffffffffffffffffffffffffffffffffffff16036104d560408c0160208d016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116104f757600061055b565b61055b8961050860208d018d6111ac565b73ffffffffffffffffffffffffffffffffffffffff160361052f60408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660808d0160608e01611326565b610b21565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b604001602081019061059a91906111ac565b6040516020016105d5919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016106079897969594939291906113db565b6000604051808303818588803b15801561062057600080fd5b505af1158015610634573d6000803e3d6000fd5b50505050505050565b60006106aa610653610100840160e085016111ac565b61066060208501856111ac565b61067060c0860160a08701611326565b61ffff1661068460408701602088016111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760408801602089016111ac565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610761919061148a565b9050610792818361077560208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff169190610b51565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc346107c161012087016101008801611326565b6107d36101408801610120890161134a565b6107e561016089016101408a0161134a565b3388806107f860408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361081f60608d0160408e016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116108415760006108a3565b6108a38a61085560408e0160208f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361087c60608e0160408f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660a08e0160808f01611326565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60600160208101906108e291906111ac565b60405160200161091d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b815260040161094f9897969594939291906113db565b6000604051808303818588803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a629085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610c3d565b50505050565b60006107d0841115610aaf576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610ac1575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610af75760646032840204610afa565b60005b9050808303838214610b1257610b128a8a8484610d51565b50505090910395945050505050565b6000612710610b3083826114d6565b610b3e9061ffff16856114f8565b610b48919061150f565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610bdd8482610e19565b610a625760405173ffffffffffffffffffffffffffffffffffffffff8416602482015260006044820152610c379085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109e0565b610a6284825b6000610c9f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610eda9092919063ffffffff16565b9050805160001480610cc0575080806020019051810190610cc0919061154a565b610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa6565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e43919061156c565b6000604051808303816000865af19150503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5091509150818015610eaf575080511580610eaf575080806020019051810190610eaf919061154a565b8015610ed1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060610ee98484600085610ef1565b949350505050565b606082471015610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fac919061156c565b60006040518083038185875af1925050503d8060008114610fe9576040519150601f19603f3d011682016040523d82523d6000602084013e610fee565b606091505b5091509150610fff8783838761100a565b979650505050505050565b606083156110a05782516000036110995773ffffffffffffffffffffffffffffffffffffffff85163b611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa6565b5081610ee9565b610ee983838151156110b55781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa69190611588565b600061016082840312156110fc57600080fd5b50919050565b600080610180838503121561111657600080fd5b61112084846110e9565b915061016083013567ffffffffffffffff81111561113d57600080fd5b83016040818603121561114f57600080fd5b809150509250929050565b6000610160828403121561116d57600080fd5b610b4883836110e9565b600061014082840312156110fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461032d57600080fd5b6000602082840312156111be57600080fd5b81356111c98161118a565b9392505050565b6000602082840312156111e257600080fd5b813565ffffffffffff811681146111c957600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261122d57600080fd5b83018035915067ffffffffffffffff82111561124857600080fd5b60200191503681900382131561125d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60006020828403121561133857600080fd5b813561ffff811681146111c957600080fd5b60006020828403121561135c57600080fd5b813560ff811681146111c957600080fd5b60005b83811015611388578181015183820152602001611370565b50506000910152565b600081518084526113a981602086016020860161136d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c084015284518184015250602084015161014083015260408401516060610160840152611454610180840182611391565b905082810360e08401526114688185611391565b838103610100850152600081529050602081019b9a5050505050505050505050565b60006020828403121561149c57600080fd5b81516111c98161118a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156114f1576114f16114a7565b5092915050565b8082028115828204841417610b4b57610b4b6114a7565b600082611545577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561155c57600080fd5b815180151581146111c957600080fd5b6000825161157e81846020870161136d565b9190910192915050565b602081526000610b48602083018461139156fea26469706673582212208328d8149ca8eb632152123f06714fc50d6667b0823eba29b328ace315d4e37464736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c80638be9f27914610039578063ba2466d41461004e578063c2bee2af14610061575b600080fd5b61004c610047366004611102565b610074565b005b61004c61005c36600461115a565b6102ce565b61004c61006f366004611177565b610330565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100d560208a018a6111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200188602001602081019061010391906111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200161012e60e08a0160c08b016111d0565b65ffffffffffff9081168252883516602091820152908252309082015260400161015e60e0880160c089016111d0565b65ffffffffffff16905261017560208601866111f8565b6040518563ffffffff1660e01b81526004016101949493929190611264565b600060405180830381600087803b1580156101ae57600080fd5b505af11580156101c2573d6000803e3d6000fd5b505050506101ed7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333061021e60408701602088016111ac565b61022b60208801886111ac565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102a957600080fd5b505af11580156102bd573d6000803e3d6000fd5b505050506102ca8261063d565b5050565b61032433306102e360408501602086016111ac565b73ffffffffffffffffffffffffffffffffffffffff1661030660208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff16929190610986565b61032d8161063d565b50565b61033d60208201826111ac565b73ffffffffffffffffffffffffffffffffffffffff1634101561038c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104026103a160e0840160c085016111ac565b60006103b360a0860160808701611326565b61ffff166103c460208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760208801886111ac565b73ffffffffffffffffffffffffffffffffffffffff16610a68565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261045060208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff1603340361047a610100860160e08701611326565b61048c6101208701610100880161134a565b61049e6101408801610120890161134a565b3387806104ae60208c018c6111ac565b73ffffffffffffffffffffffffffffffffffffffff16036104d560408c0160208d016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116104f757600061055b565b61055b8961050860208d018d6111ac565b73ffffffffffffffffffffffffffffffffffffffff160361052f60408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660808d0160608e01611326565b610b21565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b604001602081019061059a91906111ac565b6040516020016105d5919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016106079897969594939291906113db565b6000604051808303818588803b15801561062057600080fd5b505af1158015610634573d6000803e3d6000fd5b50505050505050565b60006106aa610653610100840160e085016111ac565b61066060208501856111ac565b61067060c0860160a08701611326565b61ffff1661068460408701602088016111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760408801602089016111ac565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610761919061148a565b9050610792818361077560208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff169190610b51565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc346107c161012087016101008801611326565b6107d36101408801610120890161134a565b6107e561016089016101408a0161134a565b3388806107f860408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361081f60608d0160408e016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116108415760006108a3565b6108a38a61085560408e0160208f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361087c60608e0160408f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660a08e0160808f01611326565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60600160208101906108e291906111ac565b60405160200161091d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b815260040161094f9897969594939291906113db565b6000604051808303818588803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a629085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610c3d565b50505050565b60006107d0841115610aaf576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610ac1575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610af75760646032840204610afa565b60005b9050808303838214610b1257610b128a8a8484610d51565b50505090910395945050505050565b6000612710610b3083826114d6565b610b3e9061ffff16856114f8565b610b48919061150f565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610bdd8482610e19565b610a625760405173ffffffffffffffffffffffffffffffffffffffff8416602482015260006044820152610c379085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109e0565b610a6284825b6000610c9f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610eda9092919063ffffffff16565b9050805160001480610cc0575080806020019051810190610cc0919061154a565b610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa6565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e43919061156c565b6000604051808303816000865af19150503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5091509150818015610eaf575080511580610eaf575080806020019051810190610eaf919061154a565b8015610ed1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060610ee98484600085610ef1565b949350505050565b606082471015610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fac919061156c565b60006040518083038185875af1925050503d8060008114610fe9576040519150601f19603f3d011682016040523d82523d6000602084013e610fee565b606091505b5091509150610fff8783838761100a565b979650505050505050565b606083156110a05782516000036110995773ffffffffffffffffffffffffffffffffffffffff85163b611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa6565b5081610ee9565b610ee983838151156110b55781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa69190611588565b600061016082840312156110fc57600080fd5b50919050565b600080610180838503121561111657600080fd5b61112084846110e9565b915061016083013567ffffffffffffffff81111561113d57600080fd5b83016040818603121561114f57600080fd5b809150509250929050565b6000610160828403121561116d57600080fd5b610b4883836110e9565b600061014082840312156110fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461032d57600080fd5b6000602082840312156111be57600080fd5b81356111c98161118a565b9392505050565b6000602082840312156111e257600080fd5b813565ffffffffffff811681146111c957600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261122d57600080fd5b83018035915067ffffffffffffffff82111561124857600080fd5b60200191503681900382131561125d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60006020828403121561133857600080fd5b813561ffff811681146111c957600080fd5b60006020828403121561135c57600080fd5b813560ff811681146111c957600080fd5b60005b83811015611388578181015183820152602001611370565b50506000910152565b600081518084526113a981602086016020860161136d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c084015284518184015250602084015161014083015260408401516060610160840152611454610180840182611391565b905082810360e08401526114688185611391565b838103610100850152600081529050602081019b9a5050505050505050505050565b60006020828403121561149c57600080fd5b81516111c98161118a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156114f1576114f16114a7565b5092915050565b8082028115828204841417610b4b57610b4b6114a7565b600082611545577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561155c57600080fd5b815180151581146111c957600080fd5b6000825161157e81846020870161136d565b9190910192915050565b602081526000610b48602083018461139156fea26469706673582212208328d8149ca8eb632152123f06714fc50d6667b0823eba29b328ace315d4e37464736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/avalanche/UniV2LikeFacet.json b/packages/hardhat/deployments/avalanche/UniV2LikeFacet.json index fbb964cc..07b8d82b 100644 --- a/packages/hardhat/deployments/avalanche/UniV2LikeFacet.json +++ b/packages/hardhat/deployments/avalanche/UniV2LikeFacet.json @@ -1,5 +1,5 @@ { - "address": "0xd7f9d9b2245a09457BfbCAE5F39292596C1879E9", + "address": "0xb8B3A2C8D3062cae23AbB5A0B29D6DEE88167E70", "abi": [ { "inputs": [], @@ -116,6 +116,77 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV2LikeExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -193,7 +264,83 @@ "type": "tuple" } ], - "name": "uniswapV2LikeExactInput", + "name": "uniswapV2LikeExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV2LikeExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -286,7 +433,7 @@ "type": "tuple" } ], - "name": "uniswapV2LikeExactInputSingle", + "name": "uniswapV2LikeExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -294,32 +441,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0x19383c4681bd154e9a8a4341e394daf577bdef1e921d2aaa80e01422461be7f7", + "transactionHash": "0x94c000e3fb5ef015721d9b0fee39f45c16a56b480d0d9528946e76af1f84f9c9", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xd7f9d9b2245a09457BfbCAE5F39292596C1879E9", - "transactionIndex": 7, - "gasUsed": "2101579", + "contractAddress": "0xb8B3A2C8D3062cae23AbB5A0B29D6DEE88167E70", + "transactionIndex": 1, + "gasUsed": "2340469", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x25dfafae00d3ce69b493e4c5e71654124b980e1883d4279e62331e76f07d294f", - "transactionHash": "0x19383c4681bd154e9a8a4341e394daf577bdef1e921d2aaa80e01422461be7f7", + "blockHash": "0x1c2f9587e93da573a7285a2ee59223470f5fa4cac12cdce8b5c16385057bc531", + "transactionHash": "0x94c000e3fb5ef015721d9b0fee39f45c16a56b480d0d9528946e76af1f84f9c9", "logs": [], - "blockNumber": 36642923, - "cumulativeGasUsed": "2977840", + "blockNumber": 37398401, + "cumulativeGasUsed": "2394077", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 5, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokens[0],\\n isToEth ? address(0) : params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x4d807156203d016fd7fe1ff2dd503972c0f07d9d8f1b0794aca4459c1ea03b7a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Like is ILibStarVault, ILibWarp {\\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\":\"0x80c9be72cf89c5673f0acfb44d672ae65e86062906042a31007a9737c9e1a3db\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612542806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611e34565b610066565b60405190815260200160405180910390f35b610041610061366004612036565b6109e7565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101949190612176565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb6121fd565b0497505061030189602001518a60a00151611569565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611599565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61222c565b6040518563ffffffff1660e01b81526004016104db9493929190612298565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b505050506101008a01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190612176565b90508481108061076b57506107688986612389565b81105b156107a2576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c48b60c001518c61010001518d6080015161ffff168e602001518d61162b565b985085156108f35787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108ad576040519150601f19603f3d011682016040523d82523d6000602084013e6108b2565b606091505b50509050806108ed576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610927565b6109278b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b85610937578a610100015161093a565b60005b73ffffffffffffffffffffffffffffffffffffffff168761095f578b60e00151610962565b60005b73ffffffffffffffffffffffffffffffffffffffff168c60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38e600001518d6040516109d1929190918252602082015260400190565b60405180910390a4505050505050505092915050565b60008260c0015165ffffffffffff16421115610a2f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1092916000918291908290610a7557610a7561239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610ac657610ac661239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610ba4578761010001518481518110610b0557610b0561239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9f9190612176565b610ba6565b475b90506000610bc889604001518a600001518b61010001518c61012001516116e4565b9050610bdc89602001518a60800151611569565b8160018351610beb91906123cb565b81518110610bfb57610bfb61239c565b60200260200101511015610c3b576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610d725788513414610c7b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b5050505050610d6d896101200151600081518110610d1b57610d1b61239c565b60200260200101518a600001518b6101000151600081518110610d4057610d4061239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b610fc7565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610de157610de161239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610e87919061222c565b6040518563ffffffff1660e01b8152600401610ea69493929190612298565b600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610f1557610f1561239c565b60200260200101518c600001518d6101000151600081518110610f3a57610f3a61239c565b60200260200101516040518563ffffffff1660e01b8152600401610f94949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610fae57600080fd5b505af1158015610fc2573d6000803e3d6000fd5b505050505b60005b858110156111d0576000610fdf826001612389565b905060008b61010001518281518110610ffa57610ffa61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c6101000151848151811061102f5761102f61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061105957600061105c565b60015b9050600060028d61010001515161107391906123cb565b841061107f573061109f565b8c610120015183815181106110965761109661239c565b60200260200101515b90508c610120015184815181106110b8576110b861239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836110ff578685815181106110f2576110f261239c565b6020026020010151611102565b60005b8461110e576000611129565b8786815181106111205761112061239c565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156111a957600080fd5b505af11580156111bd573d6000803e3d6000fd5b505060019095019450610fca9350505050565b50600089610100015186815181106111ea576111ea61239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190612176565b90508281108061129c57506112998884612389565b81105b156112d3576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113278a60e001518b610100015188815181106112f2576112f261239c565b60200260200101518c60a0015161ffff168d60200151868b8151811061131a5761131a61239c565b602002602001015161162b565b975083156114565786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611410576040519150601f19603f3d011682016040523d82523d6000602084013e611415565b606091505b5050905080611450576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611476565b6114768a60600151898c61010001518981518110610d4057610d4061239c565b8361149f5789610100015186815181106114925761149261239c565b60200260200101516114a2565b60005b73ffffffffffffffffffffffffffffffffffffffff16856114e2578a61010001516000815181106114d5576114d561239c565b60200260200101516114e5565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60e0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c604051611554929190918252602082015260400190565b60405180910390a45050505050505092915050565b600061271061157883826123de565b6115869061ffff1685612400565b6115909190612417565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611626908490611919565b505050565b60006107d0841115611672576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611684575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116ba57606460328402046116bd565b60005b90508083038382146116d5576116d58a8a8484611a28565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561170457611704611cff565b60405190808252806020026020018201604052801561172d578160200160208202803683370190505b50915084826000815181106117445761174461239c565b60200260200101818152505060005b8181101561190f57600085828151811061176f5761176f61239c565b602002602001015190506000868360016117899190612389565b815181106117995761179961239c565b6020026020010151905060008984815181106117b7576117b761239c565b60200260200101516127106117cc91906123de565b61ffff1690506000808886815181106117e7576117e761239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185d91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156118b857905b828b0282612710020181848d0202816118d3576118d36121fd565b049a508a886118e3886001612389565b815181106118f3576118f361239c565b6020908102919091010152505060019093019250611753915050565b5050949350505050565b600061197b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611af09092919063ffffffff16565b905080516000148061199c57508080602001905181019061199c9190612452565b611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611669565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611aff8484600085611b07565b949350505050565b606082471015611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611669565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bc2919061249f565b60006040518083038185875af1925050503d8060008114611bff576040519150601f19603f3d011682016040523d82523d6000602084013e611c04565b606091505b5091509150611c1587838387611c20565b979650505050505050565b60608315611cb6578251600003611caf5773ffffffffffffffffffffffffffffffffffffffff85163b611caf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611669565b5081611aff565b611aff8383815115611ccb5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166991906124bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611d5257611d52611cff565b60405290565b604051610140810167ffffffffffffffff81118282101715611d5257611d52611cff565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc357611dc3611cff565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611def57600080fd5b919050565b803561ffff81168114611def57600080fd5b803565ffffffffffff81168114611def57600080fd5b600060408284031215611e2e57600080fd5b50919050565b600080828403610180811215611e4957600080fd5b61016080821215611e5957600080fd5b611e61611d2e565b91508435825260208501356020830152611e7d60408601611dcb565b6040830152611e8e60608601611dcb565b6060830152611e9f60808601611df4565b6080830152611eb060a08601611df4565b60a0830152611ec160c08601611dcb565b60c0830152611ed260e08601611dcb565b60e0830152610100611ee5818701611dcb565b90830152610120611ef7868201611df4565b90830152610140611f09868201611e06565b9083015290925083013567ffffffffffffffff811115611f2857600080fd5b611f3485828601611e1c565b9150509250929050565b600067ffffffffffffffff821115611f5857611f58611cff565b5060051b60200190565b600082601f830112611f7357600080fd5b81356020611f88611f8383611f3e565b611d7c565b82815260059290921b84018101918181019086841115611fa757600080fd5b8286015b84811015611fc957611fbc81611df4565b8352918301918301611fab565b509695505050505050565b600082601f830112611fe557600080fd5b81356020611ff5611f8383611f3e565b82815260059290921b8401810191818101908684111561201457600080fd5b8286015b84811015611fc95761202981611dcb565b8352918301918301612018565b6000806040838503121561204957600080fd5b823567ffffffffffffffff8082111561206157600080fd5b90840190610140828703121561207657600080fd5b61207e611d58565b823581526020830135602082015260408301358281111561209e57600080fd5b6120aa88828601611f62565b6040830152506120bc60608401611dcb565b60608201526120cd60808401611df4565b60808201526120de60a08401611df4565b60a08201526120ef60c08401611e06565b60c082015261210060e08401611dcb565b60e0820152610100808401358381111561211957600080fd5b61212589828701611fd4565b828401525050610120808401358381111561213f57600080fd5b61214b89828701611fd4565b82840152505080945050602085013591508082111561216957600080fd5b50611f3485828601611e1c565b60006020828403121561218857600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611def57600080fd5b6000806000606084860312156121c257600080fd5b6121cb8461218f565b92506121d96020850161218f565b9150604084015163ffffffff811681146121f257600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261226157600080fd5b83018035915067ffffffffffffffff82111561227c57600080fd5b60200191503681900382131561229157600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156115935761159361235a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b818103818111156115935761159361235a565b61ffff8281168282160390808211156123f9576123f961235a565b5092915050565b80820281158282048414176115935761159361235a565b60008261244d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561246457600080fd5b8151801515811461247457600080fd5b9392505050565b60005b8381101561249657818101518382015260200161247e565b50506000910152565b600082516124b181846020870161247b565b9190910192915050565b60208152600082518060208401526124da81604085016020870161247b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220200d00eba2c244bcc4394586e11bed52f1bde27d737f84e6823312ec945bdf2064736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611e34565b610066565b60405190815260200160405180910390f35b610041610061366004612036565b6109e7565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101949190612176565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb6121fd565b0497505061030189602001518a60a00151611569565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611599565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61222c565b6040518563ffffffff1660e01b81526004016104db9493929190612298565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b505050506101008a01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190612176565b90508481108061076b57506107688986612389565b81105b156107a2576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c48b60c001518c61010001518d6080015161ffff168e602001518d61162b565b985085156108f35787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108ad576040519150601f19603f3d011682016040523d82523d6000602084013e6108b2565b606091505b50509050806108ed576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610927565b6109278b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b85610937578a610100015161093a565b60005b73ffffffffffffffffffffffffffffffffffffffff168761095f578b60e00151610962565b60005b73ffffffffffffffffffffffffffffffffffffffff168c60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38e600001518d6040516109d1929190918252602082015260400190565b60405180910390a4505050505050505092915050565b60008260c0015165ffffffffffff16421115610a2f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1092916000918291908290610a7557610a7561239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610ac657610ac661239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610ba4578761010001518481518110610b0557610b0561239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9f9190612176565b610ba6565b475b90506000610bc889604001518a600001518b61010001518c61012001516116e4565b9050610bdc89602001518a60800151611569565b8160018351610beb91906123cb565b81518110610bfb57610bfb61239c565b60200260200101511015610c3b576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610d725788513414610c7b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b5050505050610d6d896101200151600081518110610d1b57610d1b61239c565b60200260200101518a600001518b6101000151600081518110610d4057610d4061239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b610fc7565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610de157610de161239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610e87919061222c565b6040518563ffffffff1660e01b8152600401610ea69493929190612298565b600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610f1557610f1561239c565b60200260200101518c600001518d6101000151600081518110610f3a57610f3a61239c565b60200260200101516040518563ffffffff1660e01b8152600401610f94949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610fae57600080fd5b505af1158015610fc2573d6000803e3d6000fd5b505050505b60005b858110156111d0576000610fdf826001612389565b905060008b61010001518281518110610ffa57610ffa61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c6101000151848151811061102f5761102f61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061105957600061105c565b60015b9050600060028d61010001515161107391906123cb565b841061107f573061109f565b8c610120015183815181106110965761109661239c565b60200260200101515b90508c610120015184815181106110b8576110b861239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836110ff578685815181106110f2576110f261239c565b6020026020010151611102565b60005b8461110e576000611129565b8786815181106111205761112061239c565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156111a957600080fd5b505af11580156111bd573d6000803e3d6000fd5b505060019095019450610fca9350505050565b50600089610100015186815181106111ea576111ea61239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190612176565b90508281108061129c57506112998884612389565b81105b156112d3576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113278a60e001518b610100015188815181106112f2576112f261239c565b60200260200101518c60a0015161ffff168d60200151868b8151811061131a5761131a61239c565b602002602001015161162b565b975083156114565786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611410576040519150601f19603f3d011682016040523d82523d6000602084013e611415565b606091505b5050905080611450576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611476565b6114768a60600151898c61010001518981518110610d4057610d4061239c565b8361149f5789610100015186815181106114925761149261239c565b60200260200101516114a2565b60005b73ffffffffffffffffffffffffffffffffffffffff16856114e2578a61010001516000815181106114d5576114d561239c565b60200260200101516114e5565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60e0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c604051611554929190918252602082015260400190565b60405180910390a45050505050505092915050565b600061271061157883826123de565b6115869061ffff1685612400565b6115909190612417565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611626908490611919565b505050565b60006107d0841115611672576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611684575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116ba57606460328402046116bd565b60005b90508083038382146116d5576116d58a8a8484611a28565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561170457611704611cff565b60405190808252806020026020018201604052801561172d578160200160208202803683370190505b50915084826000815181106117445761174461239c565b60200260200101818152505060005b8181101561190f57600085828151811061176f5761176f61239c565b602002602001015190506000868360016117899190612389565b815181106117995761179961239c565b6020026020010151905060008984815181106117b7576117b761239c565b60200260200101516127106117cc91906123de565b61ffff1690506000808886815181106117e7576117e761239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185d91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156118b857905b828b0282612710020181848d0202816118d3576118d36121fd565b049a508a886118e3886001612389565b815181106118f3576118f361239c565b6020908102919091010152505060019093019250611753915050565b5050949350505050565b600061197b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611af09092919063ffffffff16565b905080516000148061199c57508080602001905181019061199c9190612452565b611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611669565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611aff8484600085611b07565b949350505050565b606082471015611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611669565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bc2919061249f565b60006040518083038185875af1925050503d8060008114611bff576040519150601f19603f3d011682016040523d82523d6000602084013e611c04565b606091505b5091509150611c1587838387611c20565b979650505050505050565b60608315611cb6578251600003611caf5773ffffffffffffffffffffffffffffffffffffffff85163b611caf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611669565b5081611aff565b611aff8383815115611ccb5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166991906124bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611d5257611d52611cff565b60405290565b604051610140810167ffffffffffffffff81118282101715611d5257611d52611cff565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc357611dc3611cff565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611def57600080fd5b919050565b803561ffff81168114611def57600080fd5b803565ffffffffffff81168114611def57600080fd5b600060408284031215611e2e57600080fd5b50919050565b600080828403610180811215611e4957600080fd5b61016080821215611e5957600080fd5b611e61611d2e565b91508435825260208501356020830152611e7d60408601611dcb565b6040830152611e8e60608601611dcb565b6060830152611e9f60808601611df4565b6080830152611eb060a08601611df4565b60a0830152611ec160c08601611dcb565b60c0830152611ed260e08601611dcb565b60e0830152610100611ee5818701611dcb565b90830152610120611ef7868201611df4565b90830152610140611f09868201611e06565b9083015290925083013567ffffffffffffffff811115611f2857600080fd5b611f3485828601611e1c565b9150509250929050565b600067ffffffffffffffff821115611f5857611f58611cff565b5060051b60200190565b600082601f830112611f7357600080fd5b81356020611f88611f8383611f3e565b611d7c565b82815260059290921b84018101918181019086841115611fa757600080fd5b8286015b84811015611fc957611fbc81611df4565b8352918301918301611fab565b509695505050505050565b600082601f830112611fe557600080fd5b81356020611ff5611f8383611f3e565b82815260059290921b8401810191818101908684111561201457600080fd5b8286015b84811015611fc95761202981611dcb565b8352918301918301612018565b6000806040838503121561204957600080fd5b823567ffffffffffffffff8082111561206157600080fd5b90840190610140828703121561207657600080fd5b61207e611d58565b823581526020830135602082015260408301358281111561209e57600080fd5b6120aa88828601611f62565b6040830152506120bc60608401611dcb565b60608201526120cd60808401611df4565b60808201526120de60a08401611df4565b60a08201526120ef60c08401611e06565b60c082015261210060e08401611dcb565b60e0820152610100808401358381111561211957600080fd5b61212589828701611fd4565b828401525050610120808401358381111561213f57600080fd5b61214b89828701611fd4565b82840152505080945050602085013591508082111561216957600080fd5b50611f3485828601611e1c565b60006020828403121561218857600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611def57600080fd5b6000806000606084860312156121c257600080fd5b6121cb8461218f565b92506121d96020850161218f565b9150604084015163ffffffff811681146121f257600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261226157600080fd5b83018035915067ffffffffffffffff82111561227c57600080fd5b60200191503681900382131561229157600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156115935761159361235a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b818103818111156115935761159361235a565b61ffff8281168282160390808211156123f9576123f961235a565b5092915050565b80820281158282048414176115935761159361235a565b60008261244d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561246457600080fd5b8151801515811461247457600080fd5b9392505050565b60005b8381101561249657818101518382015260200161247e565b50506000910152565b600082516124b181846020870161247b565b9190910192915050565b60208152600082518060208401526124da81604085016020870161247b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220200d00eba2c244bcc4394586e11bed52f1bde27d737f84e6823312ec945bdf2064736f6c63430008130033", + "numDeployments": 6, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"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\":\"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\":\"uniswapV2LikeExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"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\":\"uniswapV2LikeExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\\n * NOTE: The tokens must already have been moved to the first pool\\n */\\n function uniswapV2LikeExactInputSingleInternal(\\n ExactInputSingleParams memory params\\n ) internal returns (uint256 amountOut) {\\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\\n } else {\\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\\n }\\n\\n return uniswapV2LikeExactInputSingleInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 the pool\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n params.pool,\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n\\n return uniswapV2LikeExactInputSingleInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputInternal(\\n ExactInputParams calldata params\\n ) internal returns (uint256 amountOut) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n address[] memory tokens = params.tokens;\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = tokens[0] == address(0);\\n bool isToEth = tokens[poolLength] == address(0);\\n\\n if (isFromEth) {\\n tokens[0] = address(s.weth);\\n }\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : tokens[0],\\n isToEth ? address(0) : tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokens[0] == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\\n }\\n\\n return uniswapV2LikeExactInputInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\n // Permit tokens / set allowance\\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n\\n return uniswapV2LikeExactInputInternal(params);\\n }\\n}\\n\",\"keccak256\":\"0x2264d60e017f7ec8aa13691a2cabd116d785824587c832a5cb8dbaa5336599c1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Like is ILibStarVault, ILibWarp {\\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 ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInputSinglePermit(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInputPermit(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x61257f389c4a69c463baafad1a008ed2e9d68936a7e4a2cbe5a0cdc60df61e40\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b5061299a806100206000396000f3fe60806040526004361061003f5760003560e01c806311f1fdef14610044578063baa8ed3514610076578063c83ee48414610089578063d1b72bc41461009c575b600080fd5b34801561005057600080fd5b5061006461005f366004612268565b6100bc565b60405190815260200160405180910390f35b6100646100843660046122b9565b610319565b6100646100973660046122e9565b61052d565b3480156100a857600080fd5b506100646100b736600461231e565b610766565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610126906101008c01908c016123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161015d6101608b016101408c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161018f61016089016101408a016123d2565b65ffffffffffff1690526101a660208701876123ed565b6040518563ffffffff1660e01b81526004016101c59493929190612459565b600060405180830381600087803b1580156101df57600080fd5b505af11580156101f3573d6000803e3d6000fd5b5050505061021e7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c785163361024e60808701606088016123a1565b8635610261610100890160e08a016123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102df57600080fd5b505af11580156102f3573d6000803e3d6000fd5b505050506103108380360381019061030b91906125ad565b610a0c565b90505b92915050565b600061032d610160830161014084016123d2565b65ffffffffffff1642111561036e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610381610100840160e085016123a1565b73ffffffffffffffffffffffffffffffffffffffff16036104d657348235146103d6576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561046257600080fd5b505af1158015610476573d6000803e3d6000fd5b50505050506104d182606001602081019061049191906123a1565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff169084356110ca565b61051b565b61051b336104ea60808501606086016123a1565b84356104fd610100870160e088016123a1565b73ffffffffffffffffffffffffffffffffffffffff169291906111a3565b61031361030b368490038401846125ad565b600061053f60e0830160c084016123d2565b65ffffffffffff16421115610580576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610590610100840184612679565b60008181106105a1576105a16126e1565b90506020020160208101906105b691906123a1565b73ffffffffffffffffffffffffffffffffffffffff16036106ef573482351461060b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561069757600080fd5b505af11580156106ab573d6000803e3d6000fd5b50505050506106ea828061012001906106c49190612679565b60008181106106d5576106d56126e1565b905060200201602081019061049191906123a1565b61075d565b61075d33610701610120850185612679565b6000818110610712576107126126e1565b905060200201602081019061072791906123a1565b8435610737610100870187612679565b6000818110610748576107486126e1565b90506020020160208101906104fd91906123a1565b61031382611207565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915260009173ffffffffffffffffffffffffffffffffffffffff1690632b67b5709033908060608101806107c96101008b018b612679565b60008181106107da576107da6126e1565b90506020020160208101906107ef91906123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161082460e08b0160c08c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161085460e0890160c08a016123d2565b65ffffffffffff16905261086b60208701876123ed565b6040518563ffffffff1660e01b815260040161088a9493929190612459565b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506108e37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633610911610120870187612679565b6000818110610922576109226126e1565b905060200201602081019061093791906123a1565b8635610947610100890189612679565b6000818110610958576109586126e1565b905060200201602081019061096d91906123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050505061031083611207565b60e08101516101008201516000917f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff918216159116158381610af8576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af39190612710565b610afa565b475b90508215610b2057835473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8115610b4557835473ffffffffffffffffffffffffffffffffffffffff166101008701525b600080876060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915087610100015173ffffffffffffffffffffffffffffffffffffffff168860e0015173ffffffffffffffffffffffffffffffffffffffff161115610c1f57905b610120880151885161ffff6127109283031691840290820290810190830281610c4a57610c4a612797565b04975050610c6088602001518960a00151611b42565b871015610c99576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1610610cde576000610ce1565b60015b9050886060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610d0e5789610d11565b60005b83610d1d576000610d1f565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015610d8957600080fd5b505af1158015610d9d573d6000803e3d6000fd5b505050506101008901516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190612710565b905084811080610e4f5750610e4c89866127f5565b81105b15610e86576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea88a60c001518b61010001518c6080015161ffff168d602001518d611b69565b98508515610fd75787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d8060008114610f91576040519150601f19603f3d011682016040523d82523d6000602084013e610f96565b606091505b5050905080610fd1576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061100b565b61100b8a604001518a8c610100015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b8561101b5789610100015161101e565b60005b73ffffffffffffffffffffffffffffffffffffffff1687611043578a60e00151611046565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518d6040516110b5929190918252602082015260400190565b60405180910390a45050505050505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261119e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c22565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161111c565b50505050565b60007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1081611239610100850185612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061127b92505050610120860186612679565b9050905060008073ffffffffffffffffffffffffffffffffffffffff16836000815181106112ab576112ab6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168484815181106112f7576112f76126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115611387578454845173ffffffffffffffffffffffffffffffffffffffff90911690859060009061134c5761134c6126e1565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008161143f578484815181106113a0576113a06126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143a9190612710565b611441565b475b905060006114d061145560408b018b612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508c3591508990506114996101208e018e612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d3192505050565b90506114ef60208a01356114ea60a08c0160808d01612808565b611b42565b81600183516114fe9190612823565b8151811061150e5761150e6126e1565b6020026020010151101561154e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8581101561176f5760006115668260016127f5565b9050600088828151811061157c5761157c6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168984815181106115ac576115ac6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106115d65760006115d9565b60015b9050600060028a516115eb9190612823565b84106115f7573061162a565b6116056101208e018e612679565b84818110611615576116156126e1565b905060200201602081019061162a91906123a1565b905061163a6101208e018e612679565b8581811061164a5761164a6126e1565b905060200201602081019061165f91906123a1565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361169e57868581518110611691576116916126e1565b60200260200101516116a1565b60005b846116ad5760006116c8565b8786815181106116bf576116bf6126e1565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561174857600080fd5b505af115801561175c573d6000803e3d6000fd5b5050600190950194506115519350505050565b506000868681518110611784576117846126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190612710565b905082811080611836575061183389846127f5565b81105b1561186d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d66118816101008c0160e08d016123a1565b888881518110611893576118936126e1565b60200260200101518c60a00160208101906118ae9190612808565b61ffff168d60200135868b815181106118c9576118c96126e1565b6020026020010151611b69565b98508315611a125787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561194957600080fd5b505af115801561195d573d6000803e3d6000fd5b506000925061197591505060808c0160608d016123a1565b73ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146119cc576040519150601f19603f3d011682016040523d82523d6000602084013e6119d1565b606091505b5050905080611a0c576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611a65565b611a65611a2560808c0160608d016123a1565b8a898981518110611a3857611a386126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b83611a8957868681518110611a7c57611a7c6126e1565b6020026020010151611a8c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685611ac75787600081518110611aba57611aba6126e1565b6020026020010151611aca565b60005b73ffffffffffffffffffffffffffffffffffffffff16611af16101008d0160e08e016123a1565b604080518e358152602081018e905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f391016110b5565b6000612710611b518382612836565b611b5f9061ffff1685612858565b610310919061286f565b60006107d0841115611bb0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611bc2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611bf85760646032840204611bfb565b60005b9050808303838214611c1357611c138a8a8484611f66565b50505090910395945050505050565b6000611c84826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661202e9092919063ffffffff16565b9050805160001480611ca5575080806020019051810190611ca591906128aa565b61119e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611ba7565b805182516060919067ffffffffffffffff811115611d5157611d5161251b565b604051908082528060200260200182016040528015611d7a578160200160208202803683370190505b5091508482600081518110611d9157611d916126e1565b60200260200101818152505060005b81811015611f5c576000858281518110611dbc57611dbc6126e1565b60200260200101519050600086836001611dd691906127f5565b81518110611de657611de66126e1565b602002602001015190506000898481518110611e0457611e046126e1565b6020026020010151612710611e199190612836565b61ffff169050600080888681518110611e3457611e346126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115611f0557905b828b0282612710020181848d020281611f2057611f20612797565b049a508a88611f308860016127f5565b81518110611f4057611f406126e1565b6020908102919091010152505060019093019250611da0915050565b5050949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061203d8484600085612045565b949350505050565b6060824710156120d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611ba7565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161210091906128f7565b60006040518083038185875af1925050503d806000811461213d576040519150601f19603f3d011682016040523d82523d6000602084013e612142565b606091505b50915091506121538783838761215e565b979650505050505050565b606083156121f45782516000036121ed5773ffffffffffffffffffffffffffffffffffffffff85163b6121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611ba7565b508161203d565b61203d83838151156122095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79190612913565b6000610160828403121561225057600080fd5b50919050565b60006040828403121561225057600080fd5b600080610180838503121561227c57600080fd5b612286848461223d565b915061016083013567ffffffffffffffff8111156122a357600080fd5b6122af85828601612256565b9150509250929050565b600061016082840312156122cc57600080fd5b610310838361223d565b6000610140828403121561225057600080fd5b6000602082840312156122fb57600080fd5b813567ffffffffffffffff81111561231257600080fd5b61203d848285016122d6565b6000806040838503121561233157600080fd5b823567ffffffffffffffff8082111561234957600080fd5b612355868387016122d6565b9350602085013591508082111561236b57600080fd5b506122af85828601612256565b803573ffffffffffffffffffffffffffffffffffffffff8116811461239c57600080fd5b919050565b6000602082840312156123b357600080fd5b61031082612378565b803565ffffffffffff8116811461239c57600080fd5b6000602082840312156123e457600080fd5b610310826123bc565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261242257600080fd5b83018035915067ffffffffffffffff82111561243d57600080fd5b60200191503681900382131561245257600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715612595577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803561ffff8116811461239c57600080fd5b600061016082840312156125c057600080fd5b6125c861254a565b82358152602083013560208201526125e260408401612378565b60408201526125f360608401612378565b60608201526126046080840161259b565b608082015261261560a0840161259b565b60a082015261262660c08401612378565b60c082015261263760e08401612378565b60e082015261010061264a818501612378565b9082015261012061265c84820161259b565b9082015261014061266e8482016123bc565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126ae57600080fd5b83018035915067ffffffffffffffff8211156126c957600080fd5b6020019150600581901b360382131561245257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561272257600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461239c57600080fd5b60008060006060848603121561275c57600080fd5b61276584612729565b925061277360208501612729565b9150604084015163ffffffff8116811461278c57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610313576103136127c6565b60006020828403121561281a57600080fd5b6103108261259b565b81810381811115610313576103136127c6565b61ffff828116828216039080821115612851576128516127c6565b5092915050565b8082028115828204841417610313576103136127c6565b6000826128a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156128bc57600080fd5b815180151581146128cc57600080fd5b9392505050565b60005b838110156128ee5781810151838201526020016128d6565b50506000910152565b600082516129098184602087016128d3565b9190910192915050565b60208152600082518060208401526129328160408501602087016128d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de44c59485b64a44309171bd5ec5a3aa82d4e9417058be7ee66435ce87ad82ed64736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003f5760003560e01c806311f1fdef14610044578063baa8ed3514610076578063c83ee48414610089578063d1b72bc41461009c575b600080fd5b34801561005057600080fd5b5061006461005f366004612268565b6100bc565b60405190815260200160405180910390f35b6100646100843660046122b9565b610319565b6100646100973660046122e9565b61052d565b3480156100a857600080fd5b506100646100b736600461231e565b610766565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610126906101008c01908c016123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161015d6101608b016101408c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161018f61016089016101408a016123d2565b65ffffffffffff1690526101a660208701876123ed565b6040518563ffffffff1660e01b81526004016101c59493929190612459565b600060405180830381600087803b1580156101df57600080fd5b505af11580156101f3573d6000803e3d6000fd5b5050505061021e7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c785163361024e60808701606088016123a1565b8635610261610100890160e08a016123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102df57600080fd5b505af11580156102f3573d6000803e3d6000fd5b505050506103108380360381019061030b91906125ad565b610a0c565b90505b92915050565b600061032d610160830161014084016123d2565b65ffffffffffff1642111561036e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610381610100840160e085016123a1565b73ffffffffffffffffffffffffffffffffffffffff16036104d657348235146103d6576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561046257600080fd5b505af1158015610476573d6000803e3d6000fd5b50505050506104d182606001602081019061049191906123a1565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff169084356110ca565b61051b565b61051b336104ea60808501606086016123a1565b84356104fd610100870160e088016123a1565b73ffffffffffffffffffffffffffffffffffffffff169291906111a3565b61031361030b368490038401846125ad565b600061053f60e0830160c084016123d2565b65ffffffffffff16421115610580576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610590610100840184612679565b60008181106105a1576105a16126e1565b90506020020160208101906105b691906123a1565b73ffffffffffffffffffffffffffffffffffffffff16036106ef573482351461060b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561069757600080fd5b505af11580156106ab573d6000803e3d6000fd5b50505050506106ea828061012001906106c49190612679565b60008181106106d5576106d56126e1565b905060200201602081019061049191906123a1565b61075d565b61075d33610701610120850185612679565b6000818110610712576107126126e1565b905060200201602081019061072791906123a1565b8435610737610100870187612679565b6000818110610748576107486126e1565b90506020020160208101906104fd91906123a1565b61031382611207565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915260009173ffffffffffffffffffffffffffffffffffffffff1690632b67b5709033908060608101806107c96101008b018b612679565b60008181106107da576107da6126e1565b90506020020160208101906107ef91906123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161082460e08b0160c08c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161085460e0890160c08a016123d2565b65ffffffffffff16905261086b60208701876123ed565b6040518563ffffffff1660e01b815260040161088a9493929190612459565b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506108e37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633610911610120870187612679565b6000818110610922576109226126e1565b905060200201602081019061093791906123a1565b8635610947610100890189612679565b6000818110610958576109586126e1565b905060200201602081019061096d91906123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050505061031083611207565b60e08101516101008201516000917f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff918216159116158381610af8576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af39190612710565b610afa565b475b90508215610b2057835473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8115610b4557835473ffffffffffffffffffffffffffffffffffffffff166101008701525b600080876060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915087610100015173ffffffffffffffffffffffffffffffffffffffff168860e0015173ffffffffffffffffffffffffffffffffffffffff161115610c1f57905b610120880151885161ffff6127109283031691840290820290810190830281610c4a57610c4a612797565b04975050610c6088602001518960a00151611b42565b871015610c99576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1610610cde576000610ce1565b60015b9050886060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610d0e5789610d11565b60005b83610d1d576000610d1f565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015610d8957600080fd5b505af1158015610d9d573d6000803e3d6000fd5b505050506101008901516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190612710565b905084811080610e4f5750610e4c89866127f5565b81105b15610e86576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea88a60c001518b61010001518c6080015161ffff168d602001518d611b69565b98508515610fd75787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d8060008114610f91576040519150601f19603f3d011682016040523d82523d6000602084013e610f96565b606091505b5050905080610fd1576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061100b565b61100b8a604001518a8c610100015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b8561101b5789610100015161101e565b60005b73ffffffffffffffffffffffffffffffffffffffff1687611043578a60e00151611046565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518d6040516110b5929190918252602082015260400190565b60405180910390a45050505050505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261119e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c22565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161111c565b50505050565b60007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1081611239610100850185612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061127b92505050610120860186612679565b9050905060008073ffffffffffffffffffffffffffffffffffffffff16836000815181106112ab576112ab6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168484815181106112f7576112f76126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115611387578454845173ffffffffffffffffffffffffffffffffffffffff90911690859060009061134c5761134c6126e1565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008161143f578484815181106113a0576113a06126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143a9190612710565b611441565b475b905060006114d061145560408b018b612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508c3591508990506114996101208e018e612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d3192505050565b90506114ef60208a01356114ea60a08c0160808d01612808565b611b42565b81600183516114fe9190612823565b8151811061150e5761150e6126e1565b6020026020010151101561154e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8581101561176f5760006115668260016127f5565b9050600088828151811061157c5761157c6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168984815181106115ac576115ac6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106115d65760006115d9565b60015b9050600060028a516115eb9190612823565b84106115f7573061162a565b6116056101208e018e612679565b84818110611615576116156126e1565b905060200201602081019061162a91906123a1565b905061163a6101208e018e612679565b8581811061164a5761164a6126e1565b905060200201602081019061165f91906123a1565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361169e57868581518110611691576116916126e1565b60200260200101516116a1565b60005b846116ad5760006116c8565b8786815181106116bf576116bf6126e1565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561174857600080fd5b505af115801561175c573d6000803e3d6000fd5b5050600190950194506115519350505050565b506000868681518110611784576117846126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190612710565b905082811080611836575061183389846127f5565b81105b1561186d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d66118816101008c0160e08d016123a1565b888881518110611893576118936126e1565b60200260200101518c60a00160208101906118ae9190612808565b61ffff168d60200135868b815181106118c9576118c96126e1565b6020026020010151611b69565b98508315611a125787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561194957600080fd5b505af115801561195d573d6000803e3d6000fd5b506000925061197591505060808c0160608d016123a1565b73ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146119cc576040519150601f19603f3d011682016040523d82523d6000602084013e6119d1565b606091505b5050905080611a0c576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611a65565b611a65611a2560808c0160608d016123a1565b8a898981518110611a3857611a386126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b83611a8957868681518110611a7c57611a7c6126e1565b6020026020010151611a8c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685611ac75787600081518110611aba57611aba6126e1565b6020026020010151611aca565b60005b73ffffffffffffffffffffffffffffffffffffffff16611af16101008d0160e08e016123a1565b604080518e358152602081018e905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f391016110b5565b6000612710611b518382612836565b611b5f9061ffff1685612858565b610310919061286f565b60006107d0841115611bb0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611bc2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611bf85760646032840204611bfb565b60005b9050808303838214611c1357611c138a8a8484611f66565b50505090910395945050505050565b6000611c84826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661202e9092919063ffffffff16565b9050805160001480611ca5575080806020019051810190611ca591906128aa565b61119e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611ba7565b805182516060919067ffffffffffffffff811115611d5157611d5161251b565b604051908082528060200260200182016040528015611d7a578160200160208202803683370190505b5091508482600081518110611d9157611d916126e1565b60200260200101818152505060005b81811015611f5c576000858281518110611dbc57611dbc6126e1565b60200260200101519050600086836001611dd691906127f5565b81518110611de657611de66126e1565b602002602001015190506000898481518110611e0457611e046126e1565b6020026020010151612710611e199190612836565b61ffff169050600080888681518110611e3457611e346126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115611f0557905b828b0282612710020181848d020281611f2057611f20612797565b049a508a88611f308860016127f5565b81518110611f4057611f406126e1565b6020908102919091010152505060019093019250611da0915050565b5050949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061203d8484600085612045565b949350505050565b6060824710156120d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611ba7565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161210091906128f7565b60006040518083038185875af1925050503d806000811461213d576040519150601f19603f3d011682016040523d82523d6000602084013e612142565b606091505b50915091506121538783838761215e565b979650505050505050565b606083156121f45782516000036121ed5773ffffffffffffffffffffffffffffffffffffffff85163b6121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611ba7565b508161203d565b61203d83838151156122095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79190612913565b6000610160828403121561225057600080fd5b50919050565b60006040828403121561225057600080fd5b600080610180838503121561227c57600080fd5b612286848461223d565b915061016083013567ffffffffffffffff8111156122a357600080fd5b6122af85828601612256565b9150509250929050565b600061016082840312156122cc57600080fd5b610310838361223d565b6000610140828403121561225057600080fd5b6000602082840312156122fb57600080fd5b813567ffffffffffffffff81111561231257600080fd5b61203d848285016122d6565b6000806040838503121561233157600080fd5b823567ffffffffffffffff8082111561234957600080fd5b612355868387016122d6565b9350602085013591508082111561236b57600080fd5b506122af85828601612256565b803573ffffffffffffffffffffffffffffffffffffffff8116811461239c57600080fd5b919050565b6000602082840312156123b357600080fd5b61031082612378565b803565ffffffffffff8116811461239c57600080fd5b6000602082840312156123e457600080fd5b610310826123bc565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261242257600080fd5b83018035915067ffffffffffffffff82111561243d57600080fd5b60200191503681900382131561245257600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715612595577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803561ffff8116811461239c57600080fd5b600061016082840312156125c057600080fd5b6125c861254a565b82358152602083013560208201526125e260408401612378565b60408201526125f360608401612378565b60608201526126046080840161259b565b608082015261261560a0840161259b565b60a082015261262660c08401612378565b60c082015261263760e08401612378565b60e082015261010061264a818501612378565b9082015261012061265c84820161259b565b9082015261014061266e8482016123bc565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126ae57600080fd5b83018035915067ffffffffffffffff8211156126c957600080fd5b6020019150600581901b360382131561245257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561272257600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461239c57600080fd5b60008060006060848603121561275c57600080fd5b61276584612729565b925061277360208501612729565b9150604084015163ffffffff8116811461278c57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610313576103136127c6565b60006020828403121561281a57600080fd5b6103108261259b565b81810381811115610313576103136127c6565b61ffff828116828216039080821115612851576128516127c6565b5092915050565b8082028115828204841417610313576103136127c6565b6000826128a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156128bc57600080fd5b815180151581146128cc57600080fd5b9392505050565b60005b838110156128ee5781810151838201526020016128d6565b50506000910152565b600082516129098184602087016128d3565b9190910192915050565b60208152600082518060208401526129328160408501602087016128d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de44c59485b64a44309171bd5ec5a3aa82d4e9417058be7ee66435ce87ad82ed64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/avalanche/UniV3Callback.json b/packages/hardhat/deployments/avalanche/UniV3Callback.json index f862c349..c085d9c1 100644 --- a/packages/hardhat/deployments/avalanche/UniV3Callback.json +++ b/packages/hardhat/deployments/avalanche/UniV3Callback.json @@ -1,5 +1,5 @@ { - "address": "0x12Ad749fbdCF48bBc2D4aDcD00f95BA99bd13b63", + "address": "0x6Eb7651D827818B2dfdbA80E1A33743dEc3Fc701", "abi": [ { "inputs": [], @@ -122,28 +122,28 @@ "type": "function" } ], - "transactionHash": "0xd55694b7d2f9c58d3ad6a7b4bdb44c78562a90c5f9d2c1eb7d03edd803adc16d", + "transactionHash": "0x82079d5a78df79fbed7f3ae64e2501ce353d9a8f034e3895beec133a7375da53", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x12Ad749fbdCF48bBc2D4aDcD00f95BA99bd13b63", + "contractAddress": "0x6Eb7651D827818B2dfdbA80E1A33743dEc3Fc701", "transactionIndex": 3, - "gasUsed": "490767", + "gasUsed": "548027", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe39509662ca92229fc63bc7b44484d880372aed2075cedbfb3b26e14e0442896", - "transactionHash": "0xd55694b7d2f9c58d3ad6a7b4bdb44c78562a90c5f9d2c1eb7d03edd803adc16d", + "blockHash": "0xc83b097f25cb3bc6a47395f6db653a85c12f5280b4fbe194a43ef1e00ec549d8", + "transactionHash": "0x82079d5a78df79fbed7f3ae64e2501ce353d9a8f034e3895beec133a7375da53", "logs": [], - "blockNumber": 36595899, - "cumulativeGasUsed": "905229", + "blockNumber": 37398410, + "cumulativeGasUsed": "863647", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "4a9aead708515414ed961374f1d066ed", - "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\":\"pancakeV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"ramsesV2SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swapCallback\",\"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\"},\"pancakeV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"ramsesV2SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"swapCallback(int256,int256,bytes)\":{\"notice\":\"KyperSwap V2 callback 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 /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * KyperSwap V2 callback\\n * NOTE: None of these arguments can be trusted\\n */\\n function swapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x85ecd0df604a102bbc22cbcfd07afec90fd4abb25b8fac2ce0bda48ba5663f82\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107f7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610687565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d5490911692820192909252903090036101c057805160408201516101bb9173ffffffffffffffffffffffffffffffffffffffff9091169033906102d2565b610288565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561026f57600080fd5b505af1158015610283573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261035f908490610364565b505050565b60006103c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104789092919063ffffffff16565b90508051600014806103e75750808060200190518101906103e79190610707565b61035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610487848460008561048f565b949350505050565b606082471015610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046f565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161054a9190610754565b60006040518083038185875af1925050503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d878383876105a8565b979650505050505050565b6060831561063e5782516000036106375773ffffffffffffffffffffffffffffffffffffffff85163b610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046f565b5081610487565b61048783838151156106535781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046f9190610770565b6000806000806060858703121561069d57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156106c357600080fd5b818701915087601f8301126106d757600080fd5b8135818111156106e657600080fd5b8860208285010111156106f857600080fd5b95989497505060200194505050565b60006020828403121561071957600080fd5b8151801515811461072957600080fd5b9392505050565b60005b8381101561074b578181015183820152602001610733565b50506000910152565b60008251610766818460208701610730565b9190910192915050565b602081526000825180602084015261078f816040850160208701610730565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e0c3a5ea77a59d4a136519a3fb790277ee65b84323dca008c9268c0208c1cb4364736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610687565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d5490911692820192909252903090036101c057805160408201516101bb9173ffffffffffffffffffffffffffffffffffffffff9091169033906102d2565b610288565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561026f57600080fd5b505af1158015610283573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261035f908490610364565b505050565b60006103c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104789092919063ffffffff16565b90508051600014806103e75750808060200190518101906103e79190610707565b61035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610487848460008561048f565b949350505050565b606082471015610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046f565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161054a9190610754565b60006040518083038185875af1925050503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d878383876105a8565b979650505050505050565b6060831561063e5782516000036106375773ffffffffffffffffffffffffffffffffffffffff85163b610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046f565b5081610487565b61048783838151156106535781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046f9190610770565b6000806000806060858703121561069d57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156106c357600080fd5b818701915087601f8301126106d757600080fd5b8135818111156106e657600080fd5b8860208285010111156106f857600080fd5b95989497505060200194505050565b60006020828403121561071957600080fd5b8151801515811461072957600080fd5b9392505050565b60005b8381101561074b578181015183820152602001610733565b50506000910152565b60008251610766818460208701610730565b9190910192915050565b602081526000825180602084015261078f816040850160208701610730565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e0c3a5ea77a59d4a136519a3fb790277ee65b84323dca008c9268c0208c1cb4364736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "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\":\"pancakeV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"ramsesV2SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swapCallback\",\"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\"},\"pancakeV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"ramsesV2SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"swapCallback(int256,int256,bytes)\":{\"notice\":\"KyperSwap V2 callback 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 if (callback.usePermit == 1) {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n } else {\\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\\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 /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * KyperSwap V2 callback\\n * NOTE: None of these arguments can be trusted\\n */\\n function swapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xe3eb6dae32a233cc02e3aa833b2a7bac774a3c9c2c11f6d8feae8745d976f4b6\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610903806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610793565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e546060820152903090036101e757805160408201516101e29173ffffffffffffffffffffffffffffffffffffffff909116903390610339565b6102ef565b80606001516001036102bf577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156102a257600080fd5b505af11580156102b6573d6000803e3d6000fd5b505050506102ef565b6020810151815160408301516102ef9273ffffffffffffffffffffffffffffffffffffffff909116913390610412565b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261040d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610470565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526100899085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161038b565b60006104d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166105849092919063ffffffff16565b90508051600014806104f35750808060200190518101906104f39190610813565b61040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610593848460008561059b565b949350505050565b60608247101561062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161057b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106569190610860565b60006040518083038185875af1925050503d8060008114610693576040519150601f19603f3d011682016040523d82523d6000602084013e610698565b606091505b50915091506106a9878383876106b4565b979650505050505050565b6060831561074a5782516000036107435773ffffffffffffffffffffffffffffffffffffffff85163b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057b565b5081610593565b610593838381511561075f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b919061087c565b600080600080606085870312156107a957600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156107cf57600080fd5b818701915087601f8301126107e357600080fd5b8135818111156107f257600080fd5b88602082850101111561080457600080fd5b95989497505060200194505050565b60006020828403121561082557600080fd5b8151801515811461083557600080fd5b9392505050565b60005b8381101561085757818101518382015260200161083f565b50506000910152565b6000825161087281846020870161083c565b9190910192915050565b602081526000825180602084015261089b81604085016020870161083c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bd61054b7d7be6361f4cde7d339ff2b4e90fc18022d2e43caaa86ef48c70f7df64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610793565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e546060820152903090036101e757805160408201516101e29173ffffffffffffffffffffffffffffffffffffffff909116903390610339565b6102ef565b80606001516001036102bf577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156102a257600080fd5b505af11580156102b6573d6000803e3d6000fd5b505050506102ef565b6020810151815160408301516102ef9273ffffffffffffffffffffffffffffffffffffffff909116913390610412565b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261040d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610470565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526100899085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161038b565b60006104d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166105849092919063ffffffff16565b90508051600014806104f35750808060200190518101906104f39190610813565b61040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610593848460008561059b565b949350505050565b60608247101561062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161057b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106569190610860565b60006040518083038185875af1925050503d8060008114610693576040519150601f19603f3d011682016040523d82523d6000602084013e610698565b606091505b50915091506106a9878383876106b4565b979650505050505050565b6060831561074a5782516000036107435773ffffffffffffffffffffffffffffffffffffffff85163b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057b565b5081610593565b610593838381511561075f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b919061087c565b600080600080606085870312156107a957600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156107cf57600080fd5b818701915087601f8301126107e357600080fd5b8135818111156107f257600080fd5b88602082850101111561080457600080fd5b95989497505060200194505050565b60006020828403121561082557600080fd5b8151801515811461083557600080fd5b9392505050565b60005b8381101561085757818101518382015260200161083f565b50506000910152565b6000825161087281846020870161083c565b9190910192915050565b602081526000825180602084015261089b81604085016020870161083c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bd61054b7d7be6361f4cde7d339ff2b4e90fc18022d2e43caaa86ef48c70f7df64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/avalanche/UniV3Like.json b/packages/hardhat/deployments/avalanche/UniV3Like.json index e3eba312..f2a59dca 100644 --- a/packages/hardhat/deployments/avalanche/UniV3Like.json +++ b/packages/hardhat/deployments/avalanche/UniV3Like.json @@ -1,5 +1,5 @@ { - "address": "0x71e0BD402c5C0B61dE1D224824c551fE0D623065", + "address": "0x1B1a2071353424d10A33fF3D6F9AC686c8B8dC20", "abi": [ { "inputs": [], @@ -136,6 +136,72 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV3LikeExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -208,7 +274,78 @@ "type": "tuple" } ], - "name": "uniswapV3LikeExactInput", + "name": "uniswapV3LikeExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV3LikeExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -296,7 +433,7 @@ "type": "tuple" } ], - "name": "uniswapV3LikeExactInputSingle", + "name": "uniswapV3LikeExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -304,32 +441,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0x8a3646b30cc61339cae0ab30d3b6d26396ac885d24829daa7dc1ff05b786869f", + "transactionHash": "0x53f673777583f6dfbdbc9d5af1f741a2740c0022a3096c80305a48e01b535b3c", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x71e0BD402c5C0B61dE1D224824c551fE0D623065", - "transactionIndex": 3, - "gasUsed": "2039103", + "contractAddress": "0x1B1a2071353424d10A33fF3D6F9AC686c8B8dC20", + "transactionIndex": 2, + "gasUsed": "2135647", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x619b9f858f0b7cd57f8fea59580744bf5ddb21fa9969ee19e5acf53148f4f402", - "transactionHash": "0x8a3646b30cc61339cae0ab30d3b6d26396ac885d24829daa7dc1ff05b786869f", + "blockHash": "0x750b162024c4ad5fd5a30d4f97e97acc9ad7dd60b6e593768acb9efe14fa54e7", + "transactionHash": "0x53f673777583f6dfbdbc9d5af1f741a2740c0022a3096c80305a48e01b535b3c", "logs": [], - "blockNumber": 36642934, - "cumulativeGasUsed": "2547952", + "blockNumber": 37398421, + "cumulativeGasUsed": "2333758", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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/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 {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokens[0],\\n isToEth ? address(0) : params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0778264b402de681401a9d1ca9ee9e1d313e2075b7d853b1504704a605ba6c23\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\\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\":\"0x61677478daa5f86ad18959bbe4a13b95a997853f844642be3f6eb54d6ab9a772\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612421806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611de2565b610066565b60405190815260200160405180910390f35b610041610061366004611f8f565b6109f6565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029291906120a9565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff1681525089806020019061045191906120c2565b6040518563ffffffff1660e01b8152600401610470949392919061212e565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e91906121f0565b9150508061057b90612243565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906121f0565b50905061066381612243565b9550505b61066f61173b565b610682876101000151886060015161179b565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906120a9565b9050828110806107685750610765868461227b565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c188602001518960e001518a6040015161ffff168b61010001518a6117cb565b95508315610910577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108ca576040519150601f19603f3d011682016040523d82523d6000602084013e6108cf565b606091505b505090508061090a576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061093a565b875160e089015161093a9173ffffffffffffffffffffffffffffffffffffffff9091169088611884565b83610949578760e0015161094c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685610971578860c00151610974565b60005b73ffffffffffffffffffffffffffffffffffffffff16896020015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38b608001518a6040516109e3929190918252602082015260400190565b60405180910390a4505050505092915050565b60008260a0015165ffffffffffff16421115610a3e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e0840151805160009182918290610a5f57610a5f61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e001518481518110610aaf57610aaf61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610add5733610adf565b305b90508215610bfd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610b3b57610b3b61228e565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610b9a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b5050505050505b8115610c90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610c5557610c5561228e565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610ca857610ca861228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906120a9565b88519650905083610ed3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610ddb57610ddb61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610e8191906120c2565b6040518563ffffffff1660e01b8152600401610ea0949392919061212e565b600060405180830381600087803b158015610eba57600080fd5b505af1158015610ece573d6000803e3d6000fd5b505050505b60005b858110156111c457600081600101905060008a60e001518281518110610efe57610efe61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610f3257610f3261228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610fbf60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610f9957610f9961228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b80156110b65760008b61010001518481518110610fde57610fde61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a191906121f0565b915050806110ae90612243565b9950506111b1565b60008b610100015184815181106110cf576110cf61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906121f0565b5090506111ad81612243565b9950505b6111b961173b565b503093509050610ed6565b506111d386896060015161179b565b86101561120c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e0015186815181106112245761122461228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561129a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112be91906120a9565b9050818110806112d657506112d3878361227b565b81105b1561130d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113478960c001518a60e00151888151811061132b5761132b61228e565b60200260200101518b6080015161ffff168c602001518b6117cb565b96508315611496577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156113da57600080fd5b505af11580156113ee573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611450576040519150601f19603f3d011682016040523d82523d6000602084013e611455565b606091505b5050905080611490576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506114e2565b6114e28960400151888b60e0015189815181106114b5576114b561228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166118849092919063ffffffff16565b8361150a578860e0015186815181106114fd576114fd61228e565b602002602001015161150d565b60005b73ffffffffffffffffffffffffffffffffffffffff168561154c578960e0015160008151811061153f5761153f61228e565b602002602001015161154f565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b6040516115be929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611630576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611799576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60006127106117aa83826122bd565b6117b89061ffff16856122df565b6117c291906122f6565b90505b92915050565b60006107d0841115611812576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611824575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561185a576064603284020461185d565b60005b9050808303838214611875576118758a8a8484611916565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526119119084906119de565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611a40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611aed9092919063ffffffff16565b9050805160001480611a61575080806020019051810190611a619190612331565b611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611809565b6060611afc8484600085611b04565b949350505050565b606082471015611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611809565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbf919061237e565b60006040518083038185875af1925050503d8060008114611bfc576040519150601f19603f3d011682016040523d82523d6000602084013e611c01565b606091505b5091509150611c1287838387611c1d565b979650505050505050565b60608315611cb3578251600003611cac5773ffffffffffffffffffffffffffffffffffffffff85163b611cac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611809565b5081611afc565b611afc8383815115611cc85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611809919061239a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b60405290565b604051610120810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d9d57600080fd5b919050565b803561ffff81168114611d9d57600080fd5b803565ffffffffffff81168114611d9d57600080fd5b600060408284031215611ddc57600080fd5b50919050565b600080828403610160811215611df757600080fd5b61014080821215611e0757600080fd5b611e0f611d2b565b9150611e1a85611d79565b8252611e2860208601611d79565b6020830152611e3960408601611da2565b6040830152611e4a60608601611da2565b606083015260808501356080830152611e6560a08601611db4565b60a0830152611e7660c08601611d79565b60c0830152611e8760e08601611d79565b60e08301526101008581013590830152610120611ea5818701611d79565b9083015290925083013567ffffffffffffffff811115611ec457600080fd5b611ed085828601611dca565b9150509250929050565b600082601f830112611eeb57600080fd5b8135602067ffffffffffffffff80831115611f0857611f08611cfc565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611f4b57611f4b611cfc565b604052938452858101830193838101925087851115611f6957600080fd5b83870191505b84821015611c1257611f8082611d79565b83529183019190830190611f6f565b60008060408385031215611fa257600080fd5b823567ffffffffffffffff80821115611fba57600080fd5b908401906101208287031215611fcf57600080fd5b611fd7611d55565b8235815260208301356020820152611ff160408401611d79565b604082015261200260608401611da2565b606082015261201360808401611da2565b608082015261202460a08401611db4565b60a082015261203560c08401611d79565b60c082015260e08301358281111561204c57600080fd5b61205888828601611eda565b60e083015250610100808401358381111561207257600080fd5b61207e89828701611eda565b82840152505080945050602085013591508082111561209c57600080fd5b50611ed085828601611dca565b6000602082840312156120bb57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120f757600080fd5b83018035915067ffffffffffffffff82111561211257600080fd5b60200191503681900382131561212757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561220357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361227457612274612214565b5060000390565b808201808211156117c5576117c5612214565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156122d8576122d8612214565b5092915050565b80820281158282048414176117c5576117c5612214565b60008261232c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561234357600080fd5b8151801515811461235357600080fd5b9392505050565b60005b8381101561237557818101518382015260200161235d565b50506000910152565b6000825161239081846020870161235a565b9190910192915050565b60208152600082518060208401526123b981604085016020870161235a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220576050a04e57b56eff16cf6c316bc8966ab4a176dcea2edf74c13dd26adc111164736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611de2565b610066565b60405190815260200160405180910390f35b610041610061366004611f8f565b6109f6565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029291906120a9565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff1681525089806020019061045191906120c2565b6040518563ffffffff1660e01b8152600401610470949392919061212e565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e91906121f0565b9150508061057b90612243565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906121f0565b50905061066381612243565b9550505b61066f61173b565b610682876101000151886060015161179b565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906120a9565b9050828110806107685750610765868461227b565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c188602001518960e001518a6040015161ffff168b61010001518a6117cb565b95508315610910577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108ca576040519150601f19603f3d011682016040523d82523d6000602084013e6108cf565b606091505b505090508061090a576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061093a565b875160e089015161093a9173ffffffffffffffffffffffffffffffffffffffff9091169088611884565b83610949578760e0015161094c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685610971578860c00151610974565b60005b73ffffffffffffffffffffffffffffffffffffffff16896020015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38b608001518a6040516109e3929190918252602082015260400190565b60405180910390a4505050505092915050565b60008260a0015165ffffffffffff16421115610a3e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e0840151805160009182918290610a5f57610a5f61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e001518481518110610aaf57610aaf61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610add5733610adf565b305b90508215610bfd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610b3b57610b3b61228e565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610b9a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b5050505050505b8115610c90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610c5557610c5561228e565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610ca857610ca861228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906120a9565b88519650905083610ed3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610ddb57610ddb61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610e8191906120c2565b6040518563ffffffff1660e01b8152600401610ea0949392919061212e565b600060405180830381600087803b158015610eba57600080fd5b505af1158015610ece573d6000803e3d6000fd5b505050505b60005b858110156111c457600081600101905060008a60e001518281518110610efe57610efe61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610f3257610f3261228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610fbf60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610f9957610f9961228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b80156110b65760008b61010001518481518110610fde57610fde61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a191906121f0565b915050806110ae90612243565b9950506111b1565b60008b610100015184815181106110cf576110cf61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906121f0565b5090506111ad81612243565b9950505b6111b961173b565b503093509050610ed6565b506111d386896060015161179b565b86101561120c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e0015186815181106112245761122461228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561129a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112be91906120a9565b9050818110806112d657506112d3878361227b565b81105b1561130d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113478960c001518a60e00151888151811061132b5761132b61228e565b60200260200101518b6080015161ffff168c602001518b6117cb565b96508315611496577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156113da57600080fd5b505af11580156113ee573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611450576040519150601f19603f3d011682016040523d82523d6000602084013e611455565b606091505b5050905080611490576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506114e2565b6114e28960400151888b60e0015189815181106114b5576114b561228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166118849092919063ffffffff16565b8361150a578860e0015186815181106114fd576114fd61228e565b602002602001015161150d565b60005b73ffffffffffffffffffffffffffffffffffffffff168561154c578960e0015160008151811061153f5761153f61228e565b602002602001015161154f565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b6040516115be929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611630576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611799576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60006127106117aa83826122bd565b6117b89061ffff16856122df565b6117c291906122f6565b90505b92915050565b60006107d0841115611812576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611824575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561185a576064603284020461185d565b60005b9050808303838214611875576118758a8a8484611916565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526119119084906119de565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611a40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611aed9092919063ffffffff16565b9050805160001480611a61575080806020019051810190611a619190612331565b611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611809565b6060611afc8484600085611b04565b949350505050565b606082471015611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611809565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbf919061237e565b60006040518083038185875af1925050503d8060008114611bfc576040519150601f19603f3d011682016040523d82523d6000602084013e611c01565b606091505b5091509150611c1287838387611c1d565b979650505050505050565b60608315611cb3578251600003611cac5773ffffffffffffffffffffffffffffffffffffffff85163b611cac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611809565b5081611afc565b611afc8383815115611cc85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611809919061239a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b60405290565b604051610120810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d9d57600080fd5b919050565b803561ffff81168114611d9d57600080fd5b803565ffffffffffff81168114611d9d57600080fd5b600060408284031215611ddc57600080fd5b50919050565b600080828403610160811215611df757600080fd5b61014080821215611e0757600080fd5b611e0f611d2b565b9150611e1a85611d79565b8252611e2860208601611d79565b6020830152611e3960408601611da2565b6040830152611e4a60608601611da2565b606083015260808501356080830152611e6560a08601611db4565b60a0830152611e7660c08601611d79565b60c0830152611e8760e08601611d79565b60e08301526101008581013590830152610120611ea5818701611d79565b9083015290925083013567ffffffffffffffff811115611ec457600080fd5b611ed085828601611dca565b9150509250929050565b600082601f830112611eeb57600080fd5b8135602067ffffffffffffffff80831115611f0857611f08611cfc565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611f4b57611f4b611cfc565b604052938452858101830193838101925087851115611f6957600080fd5b83870191505b84821015611c1257611f8082611d79565b83529183019190830190611f6f565b60008060408385031215611fa257600080fd5b823567ffffffffffffffff80821115611fba57600080fd5b908401906101208287031215611fcf57600080fd5b611fd7611d55565b8235815260208301356020820152611ff160408401611d79565b604082015261200260608401611da2565b606082015261201360808401611da2565b608082015261202460a08401611db4565b60a082015261203560c08401611d79565b60c082015260e08301358281111561204c57600080fd5b61205888828601611eda565b60e083015250610100808401358381111561207257600080fd5b61207e89828701611eda565b82840152505080945050602085013591508082111561209c57600080fd5b50611ed085828601611dca565b6000602082840312156120bb57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120f757600080fd5b83018035915067ffffffffffffffff82111561211257600080fd5b60200191503681900382131561212757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561220357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361227457612274612214565b5060000390565b808201808211156117c5576117c5612214565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156122d8576122d8612214565b5092915050565b80820281158282048414176117c5576117c5612214565b60008261232c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561234357600080fd5b8151801515811461235357600080fd5b9392505050565b60005b8381101561237557818101518382015260200161235d565b50506000910152565b6000825161239081846020870161235a565b9190910192915050565b60208152600082518060208401526123b981604085016020870161235a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220576050a04e57b56eff16cf6c316bc8966ab4a176dcea2edf74c13dd26adc111164736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"name\":\"uniswapV3LikeExactInput\",\"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\":\"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\":\"uniswapV3LikeExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"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\":\"uniswapV3LikeExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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/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 {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\\n ExactInputSingleParams calldata params,\\n uint256 usePermit\\n ) internal returns (uint256 amountOut) {\\n bool isFromEth = params.tokenIn == address(0);\\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\\n\\n address tokenOut = params.tokenOut == address(0)\\n ? address(LibWarp.state().weth)\\n : params.tokenOut;\\n\\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = tokenIn < tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: tokenIn,\\n amount: params.amountIn,\\n usePermit: usePermit\\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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (params.tokenOut == address(0)) {\\n // To ETH, unwrap WETH\\n // TODO: This is read twice. Compare gas usage\\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(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn == address(0)) {\\n // From ETH, wrap it\\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\\n }\\n\\n function uniswapV3LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\\n }\\n\\n function uniswapV3LikeExactInputInternal(\\n ExactInputParams calldata params,\\n uint256 usePermit\\n ) internal returns (uint256 amountOut) {\\n uint256 poolLength = params.pools.length;\\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\\n address[] memory tokens = params.tokens;\\n\\n if (params.tokens[0] == address(0)) {\\n tokens[0] = address(LibWarp.state().weth);\\n }\\n\\n if (params.tokens[poolLength] == address(0)) {\\n tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: payer,\\n token: tokens[index],\\n amount: amountOut,\\n usePermit: usePermit\\n })\\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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (params.tokens[poolLength] == address(0)) {\\n // To ETH, unwrap\\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n params.tokens[0],\\n params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokens[0] == address(0)) {\\n // From ETH, wrap it\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n }\\n\\n return uniswapV3LikeExactInputInternal(params, 0);\\n }\\n\\n function uniswapV3LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 return uniswapV3LikeExactInputInternal(params, 1);\\n }\\n}\\n\",\"keccak256\":\"0x9e23653ffdee1ddba14b812d0ed30da1b28d009e139fef4562407e722f5c541f\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\\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 calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x1fbea0694f83750cccdc1e2e316bc7466e7d04e7342fd7d4359459f056d30a71\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506125e1806100206000396000f3fe60806040526004361061003e5760003560e01c80626ee8b6146100435780635576abd114610068578063a33aea141461007b578063cda932d11461009b575b600080fd5b610056610051366004612064565b6100bb565b60405190815260200160405180910390f35b6100566100763660046120ac565b61024f565b34801561008757600080fd5b506100566100963660046120db565b6103b2565b3480156100a757600080fd5b506100566100b636600461212c565b6104fc565b60006100cd60c0830160a08401612186565b65ffffffffffff1642111561010e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061011d60e08401846121ae565b600081811061012e5761012e61221d565b9050602002016020810190610143919061224c565b73ffffffffffffffffffffffffffffffffffffffff160361023e5734823514610198576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b50505050505b61024982600061065b565b92915050565b600061026160c0830160a08401612186565b65ffffffffffff164211156102a2576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b460e0840160c0850161224c565b73ffffffffffffffffffffffffffffffffffffffff16036103a7577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660808301353414610344576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561038c57600080fd5b505af11580156103a0573d6000803e3d6000fd5b5050505050505b610249826000611118565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b57091339181906060820190819061041a908b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff908116825260808b013516602082015260400161045260c08b0160a08c01612186565b65ffffffffffff9081168252893516602091820152908252309082015260400161048260c0890160a08a01612186565b65ffffffffffff1690526104996020870187612282565b6040518563ffffffff1660e01b81526004016104b894939291906122e7565b600060405180830381600087803b1580156104d257600080fd5b505af11580156104e6573d6000803e3d6000fd5b505050506104f5836001611118565b9392505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610561908b018b6121ae565b60008181106105725761057261221d565b9050602002016020810190610587919061224c565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016105bc60c08b0160a08c01612186565b65ffffffffffff908116825289351660209182015290825230908201526040016105ec60c0890160a08a01612186565b65ffffffffffff1690526106036020870187612282565b6040518563ffffffff1660e01b815260040161062294939291906122e7565b600060405180830381600087803b15801561063c57600080fd5b505af1158015610650573d6000803e3d6000fd5b505050506104f58360015b60008061066c6101008501856121ae565b9150600090508061068060e08701876121ae565b60008181106106915761069161221d565b90506020020160208101906106a6919061224c565b73ffffffffffffffffffffffffffffffffffffffff16146106c757336106c9565b305b905060006106da60e08701876121ae565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061071b9250505060e08801886121ae565b600081811061072c5761072c61221d565b9050602002016020810190610741919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036107e5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff9091169082906000906107aa576107aa61221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f460e08801886121ae565b858181106108045761080461221d565b9050602002016020810190610819919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036108be577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff909116908290859081106108835761088361221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008184815181106108d2576108d261221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c91906123a9565b87359550905060005b84811015610c8157600081600101905060008482815181106109995761099961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168584815181106109c9576109c961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610a5860405180608001604052808a81526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878681518110610a2c57610a2c61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018b815250611904565b8015610b61576000610a6e6101008c018c6121ae565b85818110610a7e57610a7e61221d565b9050602002016020810190610a93919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c91906123c2565b91505080610b5990612415565b985050610c6e565b6000610b716101008c018c6121ae565b85818110610b8157610b8161221d565b9050602002016020810190610b96919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5e91906123c2565b509050610c6a81612415565b9850505b610c76611a93565b503094509050610975565b50610c9b85610c9660808a0160608b0161244d565b611af3565b851015610cd4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828581518110610ce857610ce861221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8291906123a9565b905081811080610d9a5750610d978683612471565b81105b15610dd1576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e20610de460e08a0160c08b0161224c565b848781518110610df657610df661221d565b60200260200101518a6080016020810190610e11919061244d565b61ffff168b602001358a611b1a565b95506000610e3160e08a018a6121ae565b87818110610e4157610e4161221d565b9050602002016020810190610e56919061224c565b73ffffffffffffffffffffffffffffffffffffffff1603610fc5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b5060009250610f2891505060608a0160408b0161224c565b73ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610f7f576040519150601f19603f3d011682016040523d82523d6000602084013e610f84565b606091505b5050905080610fbf576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611018565b611018610fd860608a0160408b0161224c565b87858881518110610feb57610feb61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611bd39092919063ffffffff16565b61102560e08901896121ae565b868181106110355761103561221d565b905060200201602081019061104a919061224c565b73ffffffffffffffffffffffffffffffffffffffff1661106d60e08a018a6121ae565b600081811061107e5761107e61221d565b9050602002016020810190611093919061224c565b73ffffffffffffffffffffffffffffffffffffffff166110b960e08b0160c08c0161224c565b604080518c358152602081018b905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050505092915050565b6000808061112c60e0860160c0870161224c565b73ffffffffffffffffffffffffffffffffffffffff161490506000816111615761115c60e0860160c0870161224c565b61119a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b90506000806111b0610100880160e0890161224c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576111dc610100870160e0880161224c565b61121a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae91906123a9565b905060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610905061134860405180608001604052808a608001358152602001876113065733611308565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200189815250611904565b80156114335760006113626101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b013560448201526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e91906123c2565b9150508061142b90612415565b965050611522565b60006114476101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b0135604482015273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151291906123c2565b50905061151e81612415565b9650505b61152a611a93565b611543610100890135610c9660808b0160608c0161244d565b86101561157c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d91906123a9565b90508281108061162557506116228784612471565b81105b1561165c576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61169061166f60408b0160208c0161224c565b8561168060608d0160408e0161244d565b61ffff168c61010001358b611b1a565b965060006116a56101008b0160e08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1603611811577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d80600081146117cb576040519150601f19603f3d011682016040523d82523d6000602084013e6117d0565b606091505b505090508061180b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061183f565b61183f61182160208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff86169089611bd3565b6118506101008a0160e08b0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661187660e08b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661189c60408c0160208d0161224c565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c608001358b6040516118f0929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611962576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611af1576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612710611b028382612484565b611b109061ffff16856124a6565b6104f591906124bd565b60006107d0841115611b61576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611b73575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611ba95760646032840204611bac565b60005b9050808303838214611bc457611bc48a8a8484611c65565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611c60908490611d2d565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611d8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e3c9092919063ffffffff16565b9050805160001480611db0575080806020019051810190611db091906124f8565b611c60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611b58565b6060611e4b8484600085611e53565b949350505050565b606082471015611ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611b58565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611f0e919061253e565b60006040518083038185875af1925050503d8060008114611f4b576040519150601f19603f3d011682016040523d82523d6000602084013e611f50565b606091505b5091509150611f6187838387611f6c565b979650505050505050565b60608315612002578251600003611ffb5773ffffffffffffffffffffffffffffffffffffffff85163b611ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611b58565b5081611e4b565b611e4b83838151156120175781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b58919061255a565b6000610120828403121561205e57600080fd5b50919050565b60006020828403121561207657600080fd5b813567ffffffffffffffff81111561208d57600080fd5b611e4b8482850161204b565b6000610140828403121561205e57600080fd5b600061014082840312156120bf57600080fd5b6104f58383612099565b60006040828403121561205e57600080fd5b60008061016083850312156120ef57600080fd5b6120f98484612099565b915061014083013567ffffffffffffffff81111561211657600080fd5b612122858286016120c9565b9150509250929050565b6000806040838503121561213f57600080fd5b823567ffffffffffffffff8082111561215757600080fd5b6121638683870161204b565b9350602085013591508082111561217957600080fd5b50612122858286016120c9565b60006020828403121561219857600080fd5b813565ffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126121e357600080fd5b83018035915067ffffffffffffffff8211156121fe57600080fd5b6020019150600581901b360382131561221657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561225e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122b757600080fd5b83018035915067ffffffffffffffff8211156122d257600080fd5b60200191503681900382131561221657600080fd5b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156123bb57600080fd5b5051919050565b600080604083850312156123d557600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203612446576124466123e6565b5060000390565b60006020828403121561245f57600080fd5b813561ffff811681146104f557600080fd5b80820180821115610249576102496123e6565b61ffff82811682821603908082111561249f5761249f6123e6565b5092915050565b8082028115828204841417610249576102496123e6565b6000826124f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561250a57600080fd5b815180151581146104f557600080fd5b60005b8381101561253557818101518382015260200161251d565b50506000910152565b6000825161255081846020870161251a565b9190910192915050565b602081526000825180602084015261257981604085016020870161251a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122020ef15a82dfe9e15884ad78a08e0e295c6c50a821511c6e99799a1a517eefc3564736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003e5760003560e01c80626ee8b6146100435780635576abd114610068578063a33aea141461007b578063cda932d11461009b575b600080fd5b610056610051366004612064565b6100bb565b60405190815260200160405180910390f35b6100566100763660046120ac565b61024f565b34801561008757600080fd5b506100566100963660046120db565b6103b2565b3480156100a757600080fd5b506100566100b636600461212c565b6104fc565b60006100cd60c0830160a08401612186565b65ffffffffffff1642111561010e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061011d60e08401846121ae565b600081811061012e5761012e61221d565b9050602002016020810190610143919061224c565b73ffffffffffffffffffffffffffffffffffffffff160361023e5734823514610198576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b50505050505b61024982600061065b565b92915050565b600061026160c0830160a08401612186565b65ffffffffffff164211156102a2576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b460e0840160c0850161224c565b73ffffffffffffffffffffffffffffffffffffffff16036103a7577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660808301353414610344576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561038c57600080fd5b505af11580156103a0573d6000803e3d6000fd5b5050505050505b610249826000611118565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b57091339181906060820190819061041a908b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff908116825260808b013516602082015260400161045260c08b0160a08c01612186565b65ffffffffffff9081168252893516602091820152908252309082015260400161048260c0890160a08a01612186565b65ffffffffffff1690526104996020870187612282565b6040518563ffffffff1660e01b81526004016104b894939291906122e7565b600060405180830381600087803b1580156104d257600080fd5b505af11580156104e6573d6000803e3d6000fd5b505050506104f5836001611118565b9392505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610561908b018b6121ae565b60008181106105725761057261221d565b9050602002016020810190610587919061224c565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016105bc60c08b0160a08c01612186565b65ffffffffffff908116825289351660209182015290825230908201526040016105ec60c0890160a08a01612186565b65ffffffffffff1690526106036020870187612282565b6040518563ffffffff1660e01b815260040161062294939291906122e7565b600060405180830381600087803b15801561063c57600080fd5b505af1158015610650573d6000803e3d6000fd5b505050506104f58360015b60008061066c6101008501856121ae565b9150600090508061068060e08701876121ae565b60008181106106915761069161221d565b90506020020160208101906106a6919061224c565b73ffffffffffffffffffffffffffffffffffffffff16146106c757336106c9565b305b905060006106da60e08701876121ae565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061071b9250505060e08801886121ae565b600081811061072c5761072c61221d565b9050602002016020810190610741919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036107e5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff9091169082906000906107aa576107aa61221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f460e08801886121ae565b858181106108045761080461221d565b9050602002016020810190610819919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036108be577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff909116908290859081106108835761088361221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008184815181106108d2576108d261221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c91906123a9565b87359550905060005b84811015610c8157600081600101905060008482815181106109995761099961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168584815181106109c9576109c961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610a5860405180608001604052808a81526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878681518110610a2c57610a2c61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018b815250611904565b8015610b61576000610a6e6101008c018c6121ae565b85818110610a7e57610a7e61221d565b9050602002016020810190610a93919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c91906123c2565b91505080610b5990612415565b985050610c6e565b6000610b716101008c018c6121ae565b85818110610b8157610b8161221d565b9050602002016020810190610b96919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5e91906123c2565b509050610c6a81612415565b9850505b610c76611a93565b503094509050610975565b50610c9b85610c9660808a0160608b0161244d565b611af3565b851015610cd4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828581518110610ce857610ce861221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8291906123a9565b905081811080610d9a5750610d978683612471565b81105b15610dd1576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e20610de460e08a0160c08b0161224c565b848781518110610df657610df661221d565b60200260200101518a6080016020810190610e11919061244d565b61ffff168b602001358a611b1a565b95506000610e3160e08a018a6121ae565b87818110610e4157610e4161221d565b9050602002016020810190610e56919061224c565b73ffffffffffffffffffffffffffffffffffffffff1603610fc5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b5060009250610f2891505060608a0160408b0161224c565b73ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610f7f576040519150601f19603f3d011682016040523d82523d6000602084013e610f84565b606091505b5050905080610fbf576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611018565b611018610fd860608a0160408b0161224c565b87858881518110610feb57610feb61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611bd39092919063ffffffff16565b61102560e08901896121ae565b868181106110355761103561221d565b905060200201602081019061104a919061224c565b73ffffffffffffffffffffffffffffffffffffffff1661106d60e08a018a6121ae565b600081811061107e5761107e61221d565b9050602002016020810190611093919061224c565b73ffffffffffffffffffffffffffffffffffffffff166110b960e08b0160c08c0161224c565b604080518c358152602081018b905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050505092915050565b6000808061112c60e0860160c0870161224c565b73ffffffffffffffffffffffffffffffffffffffff161490506000816111615761115c60e0860160c0870161224c565b61119a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b90506000806111b0610100880160e0890161224c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576111dc610100870160e0880161224c565b61121a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae91906123a9565b905060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610905061134860405180608001604052808a608001358152602001876113065733611308565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200189815250611904565b80156114335760006113626101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b013560448201526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e91906123c2565b9150508061142b90612415565b965050611522565b60006114476101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b0135604482015273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151291906123c2565b50905061151e81612415565b9650505b61152a611a93565b611543610100890135610c9660808b0160608c0161244d565b86101561157c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d91906123a9565b90508281108061162557506116228784612471565b81105b1561165c576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61169061166f60408b0160208c0161224c565b8561168060608d0160408e0161244d565b61ffff168c61010001358b611b1a565b965060006116a56101008b0160e08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1603611811577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d80600081146117cb576040519150601f19603f3d011682016040523d82523d6000602084013e6117d0565b606091505b505090508061180b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061183f565b61183f61182160208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff86169089611bd3565b6118506101008a0160e08b0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661187660e08b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661189c60408c0160208d0161224c565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c608001358b6040516118f0929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611962576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611af1576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612710611b028382612484565b611b109061ffff16856124a6565b6104f591906124bd565b60006107d0841115611b61576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611b73575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611ba95760646032840204611bac565b60005b9050808303838214611bc457611bc48a8a8484611c65565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611c60908490611d2d565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611d8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e3c9092919063ffffffff16565b9050805160001480611db0575080806020019051810190611db091906124f8565b611c60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611b58565b6060611e4b8484600085611e53565b949350505050565b606082471015611ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611b58565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611f0e919061253e565b60006040518083038185875af1925050503d8060008114611f4b576040519150601f19603f3d011682016040523d82523d6000602084013e611f50565b606091505b5091509150611f6187838387611f6c565b979650505050505050565b60608315612002578251600003611ffb5773ffffffffffffffffffffffffffffffffffffffff85163b611ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611b58565b5081611e4b565b611e4b83838151156120175781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b58919061255a565b6000610120828403121561205e57600080fd5b50919050565b60006020828403121561207657600080fd5b813567ffffffffffffffff81111561208d57600080fd5b611e4b8482850161204b565b6000610140828403121561205e57600080fd5b600061014082840312156120bf57600080fd5b6104f58383612099565b60006040828403121561205e57600080fd5b60008061016083850312156120ef57600080fd5b6120f98484612099565b915061014083013567ffffffffffffffff81111561211657600080fd5b612122858286016120c9565b9150509250929050565b6000806040838503121561213f57600080fd5b823567ffffffffffffffff8082111561215757600080fd5b6121638683870161204b565b9350602085013591508082111561217957600080fd5b50612122858286016120c9565b60006020828403121561219857600080fd5b813565ffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126121e357600080fd5b83018035915067ffffffffffffffff8211156121fe57600080fd5b6020019150600581901b360382131561221657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561225e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122b757600080fd5b83018035915067ffffffffffffffff8211156122d257600080fd5b60200191503681900382131561221657600080fd5b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156123bb57600080fd5b5051919050565b600080604083850312156123d557600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203612446576124466123e6565b5060000390565b60006020828403121561245f57600080fd5b813561ffff811681146104f557600080fd5b80820180821115610249576102496123e6565b61ffff82811682821603908082111561249f5761249f6123e6565b5092915050565b8082028115828204841417610249576102496123e6565b6000826124f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561250a57600080fd5b815180151581146104f557600080fd5b60005b8381101561253557818101518382015260200161251d565b50506000910152565b6000825161255081846020870161251a565b9190910192915050565b602081526000825180602084015261257981604085016020870161251a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122020ef15a82dfe9e15884ad78a08e0e295c6c50a821511c6e99799a1a517eefc3564736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/avalanche/WarpLink.json b/packages/hardhat/deployments/avalanche/WarpLink.json index 1fce9867..6c7f4827 100644 --- a/packages/hardhat/deployments/avalanche/WarpLink.json +++ b/packages/hardhat/deployments/avalanche/WarpLink.json @@ -1,5 +1,5 @@ { - "address": "0xC28572E1a008760b204495AF30041da767F18d1B", + "address": "0xb80006779706b0f4FAd8D729B7a92b8Ca3bB6252", "abi": [ { "inputs": [], @@ -249,6 +249,71 @@ "stateMutability": "nonpayable", "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" + } + ], + "name": "warpLinkEngage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -326,34 +391,34 @@ "type": "tuple" } ], - "name": "warpLinkEngage", + "name": "warpLinkEngagePermit", "outputs": [], "stateMutability": "payable", "type": "function" } ], - "transactionHash": "0x45595bcdd4952e8811554e56be2c2f05989a5c55379e9926b6be7a32f329d86b", + "transactionHash": "0x1601a2998433b2ad9d975f1d940a1c47198404cd66a68416dc5ac568365ce635", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xC28572E1a008760b204495AF30041da767F18d1B", - "transactionIndex": 5, - "gasUsed": "4672465", + "contractAddress": "0xb80006779706b0f4FAd8D729B7a92b8Ca3bB6252", + "transactionIndex": 1, + "gasUsed": "5125542", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xb645d19eaa4aacb0434aa008a2d3662c7ea08c07d20d673f0f75d57edb9af928", - "transactionHash": "0x45595bcdd4952e8811554e56be2c2f05989a5c55379e9926b6be7a32f329d86b", + "blockHash": "0xb1a50e9b9b9b932cc30cc9581ccb8734141098df92c97ff30eac95c06dc9d4a7", + "transactionHash": "0x1601a2998433b2ad9d975f1d940a1c47198404cd66a68416dc5ac568365ce635", "logs": [], - "blockNumber": 36972819, - "cumulativeGasUsed": "5191171", + "blockNumber": 37398433, + "cumulativeGasUsed": "5335718", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 6, - "solcInputHash": "62b3897f582f2743ff2d0ddfebde07d0", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"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\":\"InvalidSgReceiveSrcAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSgReceiverSender\",\"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\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"bytes\",\"name\":\"_srcAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountLD\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sgReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{\"sgReceive(uint16,bytes,uint256,address,uint256,bytes)\":{\"notice\":\"Cross-chain callback from Stargate The tokens have already been received by this contract, `t.payer` is set to this contract before `sgReceive` is called by the router. The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the same message more than once. The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the Stargate composer be compromised, an attacker can drain this contract. If the payload can not be decoded, tokens are left in this contract. If execution runs out of gas, tokens are left in this contract. If an error occurs during engage, such as insufficient output amount, tokens are refunded to the recipient. See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\"}},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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';\\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\\n bytes payload;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n address paramTokenIn;\\n uint256 paramAmountIn;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint48 paramDeadline;\\n uint256 amount;\\n address payer;\\n address token;\\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 useEth: isFromEth || isToEth,\\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 * Cross-chain callback from Stargate\\n *\\n * The tokens have already been received by this contract, `t.payer` is set to this contract\\n * before `sgReceive` is called by the router.\\n *\\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\\n * same message more than once.\\n *\\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\\n * Stargate composer be compromised, an attacker can drain this contract.\\n *\\n * If the payload can not be decoded, tokens are left in this contract.\\n * If execution runs out of gas, tokens are left in this contract.\\n *\\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\\n * to the recipient.\\n *\\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\\n */\\n function sgReceive(\\n uint16, // _srcChainId\\n bytes memory _srcAddress,\\n uint256, // _nonce\\n address _token,\\n uint256 amountLD,\\n bytes memory payload\\n ) external {\\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\\n revert InvalidSgReceiverSender();\\n }\\n\\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\\n // From https://ethereum.stackexchange.com/a/50528\\n address srcAddress;\\n\\n assembly {\\n srcAddress := mload(add(_srcAddress, 20))\\n }\\n\\n if (srcAddress != address(this)) {\\n // NOTE: This assumes that this contract is deployed at the same address on every chain\\n revert InvalidSgReceiveSrcAddress();\\n }\\n\\n Params memory params = abi.decode(payload, (Params));\\n\\n if (params.tokenIn == address(0)) {\\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\\n // otherwise because `_token` may be different on this chain\\n _token = address(0);\\n }\\n\\n try\\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\\n Params({\\n partner: params.partner,\\n feeBps: params.feeBps,\\n slippageBps: params.slippageBps,\\n recipient: params.recipient,\\n tokenIn: _token,\\n tokenOut: params.tokenOut,\\n amountIn: amountLD,\\n amountOut: params.amountOut,\\n deadline: params.deadline,\\n commands: params.commands\\n }),\\n PermitParams({nonce: 0, signature: ''})\\n )\\n {} catch {\\n // Refund tokens to the recipient\\n if (_token == address(0)) {\\n payable(params.recipient).transfer(amountLD);\\n } else {\\n IERC20(_token).safeTransfer(params.recipient, amountLD);\\n }\\n }\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\\n * in this function.\\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 * - dstGasForCall (uint32)\\n * - tokenOut (address) when `dstGasForCall` > 0\\n * - amountOut (uint256) when `dstGasForCall` > 0\\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n params.dstGasForCall = stream.readUint32();\\n\\n if (params.dstGasForCall > 0) {\\n // NOTE: `amountIn` is left as zero\\n Params memory destParams;\\n destParams.partner = t.paramPartner;\\n destParams.feeBps = t.paramFeeBps;\\n destParams.slippageBps = t.paramSlippageBps;\\n destParams.recipient = t.paramRecipient;\\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\\n // the same address as on this chain\\n destParams.tokenIn = t.token;\\n destParams.tokenOut = stream.readAddress();\\n destParams.amountOut = stream.readUint256();\\n destParams.deadline = t.paramDeadline;\\n destParams.commands = stream.readBytes();\\n params.payload = abi.encode(destParams);\\n }\\n\\n if (t.token != t.paramTokenIn) {\\n if (params.payload.length == 0) {\\n // If the tokens are being delivered directly to the recipient without a second\\n // WarpLink engage, the fee is charged on this chain\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibStarVault.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n }\\n\\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\\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. When there is a payload, the composer is used, else the router\\n IERC20(t.token).forceApprove(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\\n t.amount\\n );\\n }\\n\\n t.jumped = 1;\\n\\n // Swap on the composer if there is a payload, else the router\\n IStargateRouter(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\\n ).swap{\\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\\n }({\\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\\n // more on the other chain. It also assumes the tokens are of nearly equal value\\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: params.dstGasForCall,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n // NOTE: This assumes the contract is deployed at the same address on every chain.\\n // If this is not the case, a new param needs to be added with the next WarpLink address\\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\\n _payload: params.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.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\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 // The signature is omitted when `warpLinkEngage` is called from `sgReceive`\\n if (permit.signature.length > 0) {\\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\\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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0x198e2bb767f975464f62ecb8578721d7516f8da1302b3acfd3c622258de1320e\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\\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 error InvalidSgReceiverSender();\\n error InvalidSgReceiveSrcAddress();\\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\":\"0xc1d8b9ba2a1f8300c00adc2c66fd51da23bb40db78ce5b7fe270bb7ee77e923e\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IStargateReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\n\\ninterface IStargateReceiver {\\n function sgReceive(\\n uint16 _srcChainId, // the remote chainId sending the tokens\\n bytes memory _srcAddress, // the remote Bridge address\\n uint256 _nonce,\\n address _token, // the token contract on the local chain\\n uint256 amountLD, // the qty of local _token contract tokens\\n bytes memory payload\\n ) external;\\n}\\n\",\"keccak256\":\"0x7fd06c09139156a4f09a77eac28e453a1d2041a8cf01a108fc875c65192cb637\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50615400806100206000396000f3fe6080604052600436106100295760003560e01c8063ab8236f31461002e578063dc7b39db14610050575b600080fd5b34801561003a57600080fd5b5061004e610049366004614a1e565b610063565b005b61004e61005e366004614af2565b61036f565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff1633146100d6576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461012a576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906101409190614c9f565b608081015190915073ffffffffffffffffffffffffffffffffffffffff1661016757600094505b3063dc7b39db73ffffffffffffffffffffffffffffffffffffffff871615610190576000610192565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff168152602001856101200151815250604051806040016040528060008152602001604051806020016040528060008152508152506040518463ffffffff1660e01b81526004016102a4929190614efc565b6000604051808303818588803b1580156102bd57600080fd5b505af1935050505080156102cf575060015b6103655773ffffffffffffffffffffffffffffffffffffffff851661033e57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610338573d6000803e3d6000fd5b50610365565b60608101516103659073ffffffffffffffffffffffffffffffffffffffff87169086610981565b5050505050505050565b81610100015165ffffffffffff164211156103b6576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015161ffff9081169184019190915260408086018051831660c08087019182526060808a01518716948801949094526080808a01805188169589019590955290890180519188019190915260e0808a015160a0890152925190941690526101008088015165ffffffffffff169186019190915291519184019190915280518216610140840152511661052a578260c00151341015610509576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08301516105189034614f63565b610180820152306101208201526106bd565b336101208201523461018082015260006105476020840184614f76565b905011156106bd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff1681525085806020019061066b9190614f76565b6040518563ffffffff1660e01b815260040161068a9493929190614fe2565b600060405180830381600087803b1580156106a457600080fd5b505af11580156106b8573d6000803e3d6000fd5b505050505b60006106e2846101200151604080518082019091528181528151909101602082015290565b90506106ee8183610a5a565b61010081015161014082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610755576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107678660e001518760400151610c37565b8210156107a0576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361016001516001036107b557505050505050565b6107d686600001518760a00151886020015161ffff168960e0015186610c65565b915081600003610812576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661087d57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610877573d6000803e3d6000fd5b506108a4565b60608601516108a49073ffffffffffffffffffffffffffffffffffffffff83169084610981565b610180840151156108e257610180840151604051339180156108fc02916000818181858888f193505050501580156108e0573d6000803e3d6000fd5b505b8560a0015173ffffffffffffffffffffffffffffffffffffffff16866080015173ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c0015186604051610971929190918252602082015260400190565b60405180910390a4505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610d1e565b505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526000610ad58480516001018051915290565b60ff16905060005b81811015610c2b576000610af78680516001018051915290565b60ff16905060018103610b1457610b0d85610e2d565b9450610c18565b60028103610b2557610b0d85610ff5565b60038103610b3757610b0d8686611254565b60048103610b4957610b0d8686611832565b60058103610b5b57610b0d8686611bb9565b60068103610b6d57610b0d8686612367565b60078103610b7f57610b0d8686612891565b60088103610b9157610b0d8686612dcf565b60098103610be657610ba4600184614f63565b8214610bdc576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d8686613205565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5080610c23816150a4565b915050610add565b50829150505b92915050565b6000612710610c4683826150dc565b610c549061ffff16856150f7565b610c5e919061513d565b9392505050565b60006107d0841115610cac576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610cbe575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610cf45760646032840204610cf7565b60005b9050808303838214610d0f57610d0f8a8a84846139d7565b50505090910395945050505050565b6000610d80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613a9f9092919063ffffffff16565b9050805160001480610da1575080806020019051810190610da19190615178565b610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ca3565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408082018390526101608201839052610180820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610f0a576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014610f5e576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50959695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146110db576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff8116301480159061110957306101208601525b600061014086015280156111bc57600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505050505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916112199160040190815260200190565b600060405180830381600087803b15801561123357600080fd5b505af1158015611247573d6000803e3d6000fd5b5096979650505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff1661130f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff90911603611404576113ff816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b6114e0565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156114c057600080fd5b505af11580156114d4573d6000803e3d6000fd5b50503061012086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161158657905b606083015161010086015161ffff61271092830316918402908202908101908302816115b4576115b461510e565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e9190615208565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161168457876101000151611687565b60005b866040015161169757600061169e565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561170857600080fd5b505af115801561171c573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b49190615208565b9050818110806117d257506101008701516117cf9083615221565b81105b15611809576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915260006118ad8480516001018051915290565b60ff16905060008361010001519050600060028310156118f9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611b84576000611914600188614f63565b82106119205785611951565b6127106119338b80516002018051915290565b61ffff168a610100015161194791906150f7565b611951919061513d565b90508581111561198d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119978187614f63565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261012080820183815261014080840185815261016085018690526101808501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d015116909152909650611a368b82610a5a565b9050806101600151600103611a77576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611a945780610120015193508061014001519450611b68565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614611afe576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614611b68576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100810151611b789087615221565b955050506001016118ff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152611c4660405180606001604052806060815260200160608152602001606081525090565b6000611c588580516001018051915290565b60ff169050611c68816001615221565b67ffffffffffffffff811115611c8057611c806148ad565b604051908082528060200260200182016040528015611ca9578160200160208202803683370190505b508083526101408501518151909190600090611cc757611cc7615234565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b81811015611d6057855160140180519087528351611d23836001615221565b81518110611d3357611d33615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611d04565b50611d6b8582613ab6565b6020830152611d7a8582613b58565b6040830152815180516000919083908110611d9757611d97615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e319190615208565b90506000611e52846040015187610100015186600001518760200151613be1565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff1603611ee457611edf8460200151600081518110611ea657611ea6615234565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b611fe3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c78516929190600090611f4357611f43615234565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b8152600401611fa9949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015611fc357600080fd5b505af1158015611fd7573d6000803e3d6000fd5b50503061012089015250505b60005b838110156121e7576000611ffb826001615221565b905060008660000151828151811061201557612015615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168760000151848151811061204957612049615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612073576000612076565b60015b90506000600288600001515161208c9190614f63565b841061209857306120b7565b876020015183815181106120ae576120ae615234565b60200260200101515b9050876020015184815181106120cf576120cf615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836121165786858151811061210957612109615234565b6020026020010151612119565b60005b84612125576000612140565b87868151811061213757612137615234565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156121c057600080fd5b505af11580156121d4573d6000803e3d6000fd5b505060019095019450611fe69350505050565b5060008460000151848151811061220057612200615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229a9190615208565b905081600183516122ab9190614f63565b815181106122bb576122bb615234565b602002602001015187610100018181525050828110806122e957506101008701516122e69084615221565b81105b15612320576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845180518590811061233457612334615234565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff90811660208301526101408401511661247a576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156124e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250c9190615208565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff161090506125a86040518060600160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff16815250613e16565b801561268c5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561264f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126739190615263565b9150508061268090615287565b61010087015250612774565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561273c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127609190615263565b50905061276c81615287565b610100870152505b61277c613f7f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e9190615208565b90508281108061282c57506101008601516128299084615221565b81105b15612863576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261291e60405180606001604052806060815260200160608152602001606081525090565b60006129308580516001018051915290565b60ff16905061293f8582613ab6565b825261294b8582613ab6565b60208301528151600090612960600184614f63565b8151811061297057612970615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156129eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0f9190615208565b905060005b83811015612cd75760008115612a4e578551612a31600184614f63565b81518110612a4157612a41615234565b6020026020010151612a55565b8761014001515b905085600001518281518110612a6d57612a6d615234565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516060810182526101008d015181526101208d01518416948101949094529184169183018290521190612ace90613e16565b82600003612ade57306101208a01525b600087602001518481518110612af657612af6615234565b602002602001015190508115612be0576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc79190615263565b91505080612bd490615287565b6101008c015250612cc4565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb09190615263565b509050612cbc81615287565b6101008c0152505b612ccc613f7f565b505050600101612a14565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6e9190615208565b905081811080612d8c5750610100870151612d899083615221565b81105b15612dc3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff9283161592918216159130911614613006577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612fe657600080fd5b505af1158015612ffa573d6000803e3d6000fd5b50503061012088015250505b6000816130a35783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561307a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309e9190615208565b6130a5565b475b9050826130e5576130e5846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff16613fdf9092919063ffffffff16565b61312a84608001518560a0015186602001518661310357600061310a565b8961010001515b886040015189606001518c610100015160008b8061312557508a5b6140d5565b6000826131c75784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561319e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c29190615208565b6131c9565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506131f38282614f63565b61010088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526132a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613431576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff166101008201528451602080820180519092010186526101208201526040516133fc9082906020016152bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613543578060800151516000036134a5578251610140840151602085015161010086015161349e93929161ffff169080610c65565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3866080015187610100015160405161353a929190918252602082015260400190565b60405180910390a45b6135558360a001518460c00151610c37565b8361010001511015613593576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff91821691161561377f5761012084015173ffffffffffffffffffffffffffffffffffffffff1630146136d1577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156136b157600080fd5b505af11580156136c5573d6000803e3d6000fd5b50503061012087015250505b61377f8260800151516000146136e75781613756565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613732573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061375691906152d2565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff169190613fdf565b6001610160850152608082015151156137985780613807565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380791906152d2565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff16146138665785610180015161387c565b85610180015186610100015161387c9190615221565b8451602086015160408701516101008a015160c08b01513091906138a1908290610c37565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c6080015151116138e7578d604001516138e9565b305b604051602001613924919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b16835261399499989796959493926004016152ef565b6000604051808303818588803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b5050600061018088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060613aae84846000856145d1565b949350505050565b60608167ffffffffffffffff811115613ad157613ad16148ad565b604051908082528060200260200182016040528015613afa578160200160208202803683370190505b50905060005b82811015613b515783516014018051908552828281518110613b2457613b24615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613b00565b5092915050565b60608167ffffffffffffffff811115613b7357613b736148ad565b604051908082528060200260200182016040528015613b9c578160200160208202803683370190505b50905060005b82811015613b515783516002018051908552828281518110613bc657613bc6615234565b61ffff90921660209283029190910190910152600101613ba2565b805182516060919067ffffffffffffffff811115613c0157613c016148ad565b604051908082528060200260200182016040528015613c2a578160200160208202803683370190505b5091508482600081518110613c4157613c41615234565b60200260200101818152505060005b81811015613e0c576000858281518110613c6c57613c6c615234565b60200260200101519050600086836001613c869190615221565b81518110613c9657613c96615234565b602002602001015190506000898481518110613cb457613cb4615234565b6020026020010151612710613cc991906150dc565b61ffff169050600080888681518110613ce457613ce4615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d5a91906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115613db557905b828b0282612710020181848d020281613dd057613dd061510e565b049a508a88613de0886001615221565b81518110613df057613df0615234565b6020908102919091010152505060019093019250613c50915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613e74576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613fdd576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261406b84826146ea565b6140cf5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526140c59085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109d3565b6140cf8482610d1e565b50505050565b8860ff1660010361420357871561418e576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561417057600080fd5b505af1158015614184573d6000803e3d6000fd5b50505050506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614157565b8860ff166002036143435787156142ce576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156142a3573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906142c89190615208565b506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614285565b8860ff166003036144e45787156143c1576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614285565b801561443b576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614285565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af11580156144c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c89190615208565b8860ff16600403614594578715614527576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614157565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b606082471015614663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ca3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161468c919061539b565b60006040518083038185875af1925050503d80600081146146c9576040519150601f19603f3d011682016040523d82523d6000602084013e6146ce565b606091505b50915091506146df878383876147ab565b979650505050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614714919061539b565b6000604051808303816000865af19150503d8060008114614751576040519150601f19603f3d011682016040523d82523d6000602084013e614756565b606091505b50915091508180156147805750805115806147805750808060200190518101906147809190615178565b80156147a2575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060831561484157825160000361483a5773ffffffffffffffffffffffffffffffffffffffff85163b61483a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca3565b5081613aae565b613aae83838151156148565781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca391906153b7565b61ffff8116811461489a57600080fd5b50565b80356148a88161488a565b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614900576149006148ad565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561494d5761494d6148ad565b604052919050565b600067ffffffffffffffff82111561496f5761496f6148ad565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149ac57600080fd5b81356149bf6149ba82614955565b614906565b8181528460208386010111156149d457600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461489a57600080fd5b80356148a8816149f1565b60008060008060008060c08789031215614a3757600080fd5b8635614a428161488a565b9550602087013567ffffffffffffffff80821115614a5f57600080fd5b614a6b8a838b0161499b565b96506040890135955060608901359150614a84826149f1565b9093506080880135925060a08801359080821115614aa157600080fd5b50614aae89828a0161499b565b9150509295509295509295565b65ffffffffffff8116811461489a57600080fd5b80356148a881614abb565b600060408284031215614aec57600080fd5b50919050565b60008060408385031215614b0557600080fd5b823567ffffffffffffffff80821115614b1d57600080fd5b908401906101408287031215614b3257600080fd5b614b3a6148dc565b614b4383614a13565b8152614b516020840161489d565b6020820152614b626040840161489d565b6040820152614b7360608401614a13565b6060820152614b8460808401614a13565b6080820152614b9560a08401614a13565b60a082015260c083013560c082015260e083013560e0820152610100614bbc818501614acf565b908201526101208381013583811115614bd457600080fd5b614be08982870161499b565b828401525050809450506020850135915080821115614bfe57600080fd5b50614c0b85828601614ada565b9150509250929050565b80516148a8816149f1565b80516148a88161488a565b80516148a881614abb565b60005b83811015614c51578181015183820152602001614c39565b50506000910152565b600082601f830112614c6b57600080fd5b8151614c796149ba82614955565b818152846020838601011115614c8e57600080fd5b613aae826020830160208701614c36565b600060208284031215614cb157600080fd5b815167ffffffffffffffff80821115614cc957600080fd5b908301906101408286031215614cde57600080fd5b614ce66148dc565b614cef83614c15565b8152614cfd60208401614c20565b6020820152614d0e60408401614c20565b6040820152614d1f60608401614c15565b6060820152614d3060808401614c15565b6080820152614d4160a08401614c15565b60a082015260c083015160c082015260e083015160e0820152610100614d68818501614c2b565b908201526101208381015183811115614d8057600080fd5b614d8c88828701614c5a565b918301919091525095945050505050565b60008151808452614db5816020860160208601614c36565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006101406020830151614e1b602086018261ffff169052565b506040830151614e31604086018261ffff169052565b506060830151614e59606086018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151614e81608086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614ea960a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015160c085015260e083015160e085015261010080840151614ed88287018265ffffffffffff169052565b5050610120808401518282870152614ef283870182614d9d565b9695505050505050565b604081526000614f0f6040830185614de7565b828103602084015283518152602084015160406020830152614ef26040830182614d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c3157610c31614f34565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614fab57600080fd5b83018035915067ffffffffffffffff821115614fc657600080fd5b602001915036819003821315614fdb57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150d5576150d5614f34565b5060010190565b61ffff828116828216039080821115613b5157613b51614f34565b8082028115828204841417610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615173577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561518a57600080fd5b81518015158114610c5e57600080fd5b80516dffffffffffffffffffffffffffff811681146148a857600080fd5b6000806000606084860312156151cd57600080fd5b6151d68461519a565b92506151e46020850161519a565b9150604084015163ffffffff811681146151fd57600080fd5b809150509250925092565b60006020828403121561521a57600080fd5b5051919050565b80820180821115610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561527657600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036152b8576152b8614f34565b5060000390565b602081526000610c5e6020830184614de7565b6000602082840312156152e457600080fd5b8151610c5e816149f1565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615362610180840182614d9d565b905082810360e08401526153768186614d9d565b905082810361010084015261538b8185614d9d565b9c9b505050505050505050505050565b600082516153ad818460208701614c36565b9190910192915050565b602081526000610c5e6020830184614d9d56fea26469706673582212204eecdc76d361ea4a608ec1291a66f39b61f591d844e03c8f4164adb5e8c419c464736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c8063ab8236f31461002e578063dc7b39db14610050575b600080fd5b34801561003a57600080fd5b5061004e610049366004614a1e565b610063565b005b61004e61005e366004614af2565b61036f565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff1633146100d6576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461012a576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906101409190614c9f565b608081015190915073ffffffffffffffffffffffffffffffffffffffff1661016757600094505b3063dc7b39db73ffffffffffffffffffffffffffffffffffffffff871615610190576000610192565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff168152602001856101200151815250604051806040016040528060008152602001604051806020016040528060008152508152506040518463ffffffff1660e01b81526004016102a4929190614efc565b6000604051808303818588803b1580156102bd57600080fd5b505af1935050505080156102cf575060015b6103655773ffffffffffffffffffffffffffffffffffffffff851661033e57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610338573d6000803e3d6000fd5b50610365565b60608101516103659073ffffffffffffffffffffffffffffffffffffffff87169086610981565b5050505050505050565b81610100015165ffffffffffff164211156103b6576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015161ffff9081169184019190915260408086018051831660c08087019182526060808a01518716948801949094526080808a01805188169589019590955290890180519188019190915260e0808a015160a0890152925190941690526101008088015165ffffffffffff169186019190915291519184019190915280518216610140840152511661052a578260c00151341015610509576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08301516105189034614f63565b610180820152306101208201526106bd565b336101208201523461018082015260006105476020840184614f76565b905011156106bd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff1681525085806020019061066b9190614f76565b6040518563ffffffff1660e01b815260040161068a9493929190614fe2565b600060405180830381600087803b1580156106a457600080fd5b505af11580156106b8573d6000803e3d6000fd5b505050505b60006106e2846101200151604080518082019091528181528151909101602082015290565b90506106ee8183610a5a565b61010081015161014082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610755576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107678660e001518760400151610c37565b8210156107a0576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361016001516001036107b557505050505050565b6107d686600001518760a00151886020015161ffff168960e0015186610c65565b915081600003610812576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661087d57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610877573d6000803e3d6000fd5b506108a4565b60608601516108a49073ffffffffffffffffffffffffffffffffffffffff83169084610981565b610180840151156108e257610180840151604051339180156108fc02916000818181858888f193505050501580156108e0573d6000803e3d6000fd5b505b8560a0015173ffffffffffffffffffffffffffffffffffffffff16866080015173ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c0015186604051610971929190918252602082015260400190565b60405180910390a4505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610d1e565b505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526000610ad58480516001018051915290565b60ff16905060005b81811015610c2b576000610af78680516001018051915290565b60ff16905060018103610b1457610b0d85610e2d565b9450610c18565b60028103610b2557610b0d85610ff5565b60038103610b3757610b0d8686611254565b60048103610b4957610b0d8686611832565b60058103610b5b57610b0d8686611bb9565b60068103610b6d57610b0d8686612367565b60078103610b7f57610b0d8686612891565b60088103610b9157610b0d8686612dcf565b60098103610be657610ba4600184614f63565b8214610bdc576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d8686613205565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5080610c23816150a4565b915050610add565b50829150505b92915050565b6000612710610c4683826150dc565b610c549061ffff16856150f7565b610c5e919061513d565b9392505050565b60006107d0841115610cac576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610cbe575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610cf45760646032840204610cf7565b60005b9050808303838214610d0f57610d0f8a8a84846139d7565b50505090910395945050505050565b6000610d80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613a9f9092919063ffffffff16565b9050805160001480610da1575080806020019051810190610da19190615178565b610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ca3565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408082018390526101608201839052610180820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610f0a576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014610f5e576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50959695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146110db576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff8116301480159061110957306101208601525b600061014086015280156111bc57600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505050505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916112199160040190815260200190565b600060405180830381600087803b15801561123357600080fd5b505af1158015611247573d6000803e3d6000fd5b5096979650505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff1661130f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff90911603611404576113ff816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b6114e0565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156114c057600080fd5b505af11580156114d4573d6000803e3d6000fd5b50503061012086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161158657905b606083015161010086015161ffff61271092830316918402908202908101908302816115b4576115b461510e565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e9190615208565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161168457876101000151611687565b60005b866040015161169757600061169e565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561170857600080fd5b505af115801561171c573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b49190615208565b9050818110806117d257506101008701516117cf9083615221565b81105b15611809576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915260006118ad8480516001018051915290565b60ff16905060008361010001519050600060028310156118f9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611b84576000611914600188614f63565b82106119205785611951565b6127106119338b80516002018051915290565b61ffff168a610100015161194791906150f7565b611951919061513d565b90508581111561198d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119978187614f63565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261012080820183815261014080840185815261016085018690526101808501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d015116909152909650611a368b82610a5a565b9050806101600151600103611a77576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611a945780610120015193508061014001519450611b68565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614611afe576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614611b68576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100810151611b789087615221565b955050506001016118ff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152611c4660405180606001604052806060815260200160608152602001606081525090565b6000611c588580516001018051915290565b60ff169050611c68816001615221565b67ffffffffffffffff811115611c8057611c806148ad565b604051908082528060200260200182016040528015611ca9578160200160208202803683370190505b508083526101408501518151909190600090611cc757611cc7615234565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b81811015611d6057855160140180519087528351611d23836001615221565b81518110611d3357611d33615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611d04565b50611d6b8582613ab6565b6020830152611d7a8582613b58565b6040830152815180516000919083908110611d9757611d97615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e319190615208565b90506000611e52846040015187610100015186600001518760200151613be1565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff1603611ee457611edf8460200151600081518110611ea657611ea6615234565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b611fe3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c78516929190600090611f4357611f43615234565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b8152600401611fa9949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015611fc357600080fd5b505af1158015611fd7573d6000803e3d6000fd5b50503061012089015250505b60005b838110156121e7576000611ffb826001615221565b905060008660000151828151811061201557612015615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168760000151848151811061204957612049615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612073576000612076565b60015b90506000600288600001515161208c9190614f63565b841061209857306120b7565b876020015183815181106120ae576120ae615234565b60200260200101515b9050876020015184815181106120cf576120cf615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836121165786858151811061210957612109615234565b6020026020010151612119565b60005b84612125576000612140565b87868151811061213757612137615234565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156121c057600080fd5b505af11580156121d4573d6000803e3d6000fd5b505060019095019450611fe69350505050565b5060008460000151848151811061220057612200615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229a9190615208565b905081600183516122ab9190614f63565b815181106122bb576122bb615234565b602002602001015187610100018181525050828110806122e957506101008701516122e69084615221565b81105b15612320576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845180518590811061233457612334615234565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff90811660208301526101408401511661247a576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156124e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250c9190615208565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff161090506125a86040518060600160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff16815250613e16565b801561268c5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561264f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126739190615263565b9150508061268090615287565b61010087015250612774565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561273c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127609190615263565b50905061276c81615287565b610100870152505b61277c613f7f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e9190615208565b90508281108061282c57506101008601516128299084615221565b81105b15612863576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261291e60405180606001604052806060815260200160608152602001606081525090565b60006129308580516001018051915290565b60ff16905061293f8582613ab6565b825261294b8582613ab6565b60208301528151600090612960600184614f63565b8151811061297057612970615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156129eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0f9190615208565b905060005b83811015612cd75760008115612a4e578551612a31600184614f63565b81518110612a4157612a41615234565b6020026020010151612a55565b8761014001515b905085600001518281518110612a6d57612a6d615234565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516060810182526101008d015181526101208d01518416948101949094529184169183018290521190612ace90613e16565b82600003612ade57306101208a01525b600087602001518481518110612af657612af6615234565b602002602001015190508115612be0576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc79190615263565b91505080612bd490615287565b6101008c015250612cc4565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb09190615263565b509050612cbc81615287565b6101008c0152505b612ccc613f7f565b505050600101612a14565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6e9190615208565b905081811080612d8c5750610100870151612d899083615221565b81105b15612dc3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff9283161592918216159130911614613006577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612fe657600080fd5b505af1158015612ffa573d6000803e3d6000fd5b50503061012088015250505b6000816130a35783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561307a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309e9190615208565b6130a5565b475b9050826130e5576130e5846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff16613fdf9092919063ffffffff16565b61312a84608001518560a0015186602001518661310357600061310a565b8961010001515b886040015189606001518c610100015160008b8061312557508a5b6140d5565b6000826131c75784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561319e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c29190615208565b6131c9565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506131f38282614f63565b61010088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526132a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613431576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff166101008201528451602080820180519092010186526101208201526040516133fc9082906020016152bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613543578060800151516000036134a5578251610140840151602085015161010086015161349e93929161ffff169080610c65565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3866080015187610100015160405161353a929190918252602082015260400190565b60405180910390a45b6135558360a001518460c00151610c37565b8361010001511015613593576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff91821691161561377f5761012084015173ffffffffffffffffffffffffffffffffffffffff1630146136d1577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156136b157600080fd5b505af11580156136c5573d6000803e3d6000fd5b50503061012087015250505b61377f8260800151516000146136e75781613756565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613732573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061375691906152d2565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff169190613fdf565b6001610160850152608082015151156137985780613807565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380791906152d2565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff16146138665785610180015161387c565b85610180015186610100015161387c9190615221565b8451602086015160408701516101008a015160c08b01513091906138a1908290610c37565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c6080015151116138e7578d604001516138e9565b305b604051602001613924919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b16835261399499989796959493926004016152ef565b6000604051808303818588803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b5050600061018088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060613aae84846000856145d1565b949350505050565b60608167ffffffffffffffff811115613ad157613ad16148ad565b604051908082528060200260200182016040528015613afa578160200160208202803683370190505b50905060005b82811015613b515783516014018051908552828281518110613b2457613b24615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613b00565b5092915050565b60608167ffffffffffffffff811115613b7357613b736148ad565b604051908082528060200260200182016040528015613b9c578160200160208202803683370190505b50905060005b82811015613b515783516002018051908552828281518110613bc657613bc6615234565b61ffff90921660209283029190910190910152600101613ba2565b805182516060919067ffffffffffffffff811115613c0157613c016148ad565b604051908082528060200260200182016040528015613c2a578160200160208202803683370190505b5091508482600081518110613c4157613c41615234565b60200260200101818152505060005b81811015613e0c576000858281518110613c6c57613c6c615234565b60200260200101519050600086836001613c869190615221565b81518110613c9657613c96615234565b602002602001015190506000898481518110613cb457613cb4615234565b6020026020010151612710613cc991906150dc565b61ffff169050600080888681518110613ce457613ce4615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d5a91906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115613db557905b828b0282612710020181848d020281613dd057613dd061510e565b049a508a88613de0886001615221565b81518110613df057613df0615234565b6020908102919091010152505060019093019250613c50915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613e74576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613fdd576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261406b84826146ea565b6140cf5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526140c59085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109d3565b6140cf8482610d1e565b50505050565b8860ff1660010361420357871561418e576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561417057600080fd5b505af1158015614184573d6000803e3d6000fd5b50505050506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614157565b8860ff166002036143435787156142ce576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156142a3573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906142c89190615208565b506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614285565b8860ff166003036144e45787156143c1576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614285565b801561443b576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614285565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af11580156144c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c89190615208565b8860ff16600403614594578715614527576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614157565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b606082471015614663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ca3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161468c919061539b565b60006040518083038185875af1925050503d80600081146146c9576040519150601f19603f3d011682016040523d82523d6000602084013e6146ce565b606091505b50915091506146df878383876147ab565b979650505050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614714919061539b565b6000604051808303816000865af19150503d8060008114614751576040519150601f19603f3d011682016040523d82523d6000602084013e614756565b606091505b50915091508180156147805750805115806147805750808060200190518101906147809190615178565b80156147a2575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060831561484157825160000361483a5773ffffffffffffffffffffffffffffffffffffffff85163b61483a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca3565b5081613aae565b613aae83838151156148565781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca391906153b7565b61ffff8116811461489a57600080fd5b50565b80356148a88161488a565b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614900576149006148ad565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561494d5761494d6148ad565b604052919050565b600067ffffffffffffffff82111561496f5761496f6148ad565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149ac57600080fd5b81356149bf6149ba82614955565b614906565b8181528460208386010111156149d457600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461489a57600080fd5b80356148a8816149f1565b60008060008060008060c08789031215614a3757600080fd5b8635614a428161488a565b9550602087013567ffffffffffffffff80821115614a5f57600080fd5b614a6b8a838b0161499b565b96506040890135955060608901359150614a84826149f1565b9093506080880135925060a08801359080821115614aa157600080fd5b50614aae89828a0161499b565b9150509295509295509295565b65ffffffffffff8116811461489a57600080fd5b80356148a881614abb565b600060408284031215614aec57600080fd5b50919050565b60008060408385031215614b0557600080fd5b823567ffffffffffffffff80821115614b1d57600080fd5b908401906101408287031215614b3257600080fd5b614b3a6148dc565b614b4383614a13565b8152614b516020840161489d565b6020820152614b626040840161489d565b6040820152614b7360608401614a13565b6060820152614b8460808401614a13565b6080820152614b9560a08401614a13565b60a082015260c083013560c082015260e083013560e0820152610100614bbc818501614acf565b908201526101208381013583811115614bd457600080fd5b614be08982870161499b565b828401525050809450506020850135915080821115614bfe57600080fd5b50614c0b85828601614ada565b9150509250929050565b80516148a8816149f1565b80516148a88161488a565b80516148a881614abb565b60005b83811015614c51578181015183820152602001614c39565b50506000910152565b600082601f830112614c6b57600080fd5b8151614c796149ba82614955565b818152846020838601011115614c8e57600080fd5b613aae826020830160208701614c36565b600060208284031215614cb157600080fd5b815167ffffffffffffffff80821115614cc957600080fd5b908301906101408286031215614cde57600080fd5b614ce66148dc565b614cef83614c15565b8152614cfd60208401614c20565b6020820152614d0e60408401614c20565b6040820152614d1f60608401614c15565b6060820152614d3060808401614c15565b6080820152614d4160a08401614c15565b60a082015260c083015160c082015260e083015160e0820152610100614d68818501614c2b565b908201526101208381015183811115614d8057600080fd5b614d8c88828701614c5a565b918301919091525095945050505050565b60008151808452614db5816020860160208601614c36565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006101406020830151614e1b602086018261ffff169052565b506040830151614e31604086018261ffff169052565b506060830151614e59606086018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151614e81608086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614ea960a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015160c085015260e083015160e085015261010080840151614ed88287018265ffffffffffff169052565b5050610120808401518282870152614ef283870182614d9d565b9695505050505050565b604081526000614f0f6040830185614de7565b828103602084015283518152602084015160406020830152614ef26040830182614d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c3157610c31614f34565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614fab57600080fd5b83018035915067ffffffffffffffff821115614fc657600080fd5b602001915036819003821315614fdb57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150d5576150d5614f34565b5060010190565b61ffff828116828216039080821115613b5157613b51614f34565b8082028115828204841417610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615173577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561518a57600080fd5b81518015158114610c5e57600080fd5b80516dffffffffffffffffffffffffffff811681146148a857600080fd5b6000806000606084860312156151cd57600080fd5b6151d68461519a565b92506151e46020850161519a565b9150604084015163ffffffff811681146151fd57600080fd5b809150509250925092565b60006020828403121561521a57600080fd5b5051919050565b80820180821115610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561527657600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036152b8576152b8614f34565b5060000390565b602081526000610c5e6020830184614de7565b6000602082840312156152e457600080fd5b8151610c5e816149f1565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615362610180840182614d9d565b905082810360e08401526153768186614d9d565b905082810361010084015261538b8185614d9d565b9c9b505050505050505050505050565b600082516153ad818460208701614c36565b9190910192915050565b602081526000610c5e6020830184614d9d56fea26469706673582212204eecdc76d361ea4a608ec1291a66f39b61f591d844e03c8f4164adb5e8c419c464736f6c63430008130033", + "numDeployments": 7, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"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\":\"InvalidSgReceiveSrcAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSgReceiverSender\",\"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\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"bytes\",\"name\":\"_srcAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountLD\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sgReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"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\":\"warpLinkEngagePermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{\"sgReceive(uint16,bytes,uint256,address,uint256,bytes)\":{\"notice\":\"Cross-chain callback from Stargate The tokens have already been received by this contract, `t.payer` is set to this contract before `sgReceive` is called by the router. The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the same message more than once. The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the Stargate composer be compromised, an attacker can drain this contract. If the payload can not be decoded, tokens are left in this contract. If execution runs out of gas, tokens are left in this contract. If an error occurs during engage, such as insufficient output amount, tokens are refunded to the recipient. See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\"}},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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';\\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\\n bytes payload;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n address paramTokenIn;\\n uint256 paramAmountIn;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint48 paramDeadline;\\n uint256 amount;\\n address payer;\\n address token;\\n /**\\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\\n */\\n uint256 usePermit;\\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 if (t.usePermit == 1) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\\n }\\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 if (t.usePermit == 1) {\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\\n }\\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 if (t.usePermit == 1) {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(\\n t.payer,\\n params.pools[0],\\n (uint160)(t.amount),\\n t.token\\n );\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\\n }\\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({\\n payer: t.payer,\\n token: t.token,\\n amount: t.amount,\\n usePermit: t.usePermit\\n })\\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({\\n payer: t.payer,\\n token: tokenIn,\\n amount: t.amount,\\n usePermit: t.usePermit\\n })\\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 if (t.usePermit == 1) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\\n }\\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 useEth: isFromEth || isToEth,\\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 * Cross-chain callback from Stargate\\n *\\n * The tokens have already been received by this contract, `t.payer` is set to this contract\\n * before `sgReceive` is called by the router.\\n *\\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\\n * same message more than once.\\n *\\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\\n * Stargate composer be compromised, an attacker can drain this contract.\\n *\\n * If the payload can not be decoded, tokens are left in this contract.\\n * If execution runs out of gas, tokens are left in this contract.\\n *\\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\\n * to the recipient.\\n *\\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\\n */\\n function sgReceive(\\n uint16, // _srcChainId\\n bytes memory _srcAddress,\\n uint256, // _nonce\\n address _token,\\n uint256 amountLD,\\n bytes memory payload\\n ) external {\\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\\n revert InvalidSgReceiverSender();\\n }\\n\\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\\n // From https://ethereum.stackexchange.com/a/50528\\n address srcAddress;\\n\\n assembly {\\n srcAddress := mload(add(_srcAddress, 20))\\n }\\n\\n if (srcAddress != address(this)) {\\n // NOTE: This assumes that this contract is deployed at the same address on every chain\\n revert InvalidSgReceiveSrcAddress();\\n }\\n\\n Params memory params = abi.decode(payload, (Params));\\n\\n if (params.tokenIn == address(0)) {\\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\\n // otherwise because `_token` may be different on this chain\\n _token = address(0);\\n }\\n\\n try\\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\\n Params({\\n partner: params.partner,\\n feeBps: params.feeBps,\\n slippageBps: params.slippageBps,\\n recipient: params.recipient,\\n tokenIn: _token,\\n tokenOut: params.tokenOut,\\n amountIn: amountLD,\\n amountOut: params.amountOut,\\n deadline: params.deadline,\\n commands: params.commands\\n })\\n )\\n {} catch {\\n // Refund tokens to the recipient\\n if (_token == address(0)) {\\n payable(params.recipient).transfer(amountLD);\\n } else {\\n IERC20(_token).safeTransfer(params.recipient, amountLD);\\n }\\n }\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\\n * in this function.\\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 * - dstGasForCall (uint32)\\n * - tokenOut (address) when `dstGasForCall` > 0\\n * - amountOut (uint256) when `dstGasForCall` > 0\\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n params.dstGasForCall = stream.readUint32();\\n\\n if (params.dstGasForCall > 0) {\\n // NOTE: `amountIn` is left as zero\\n Params memory destParams;\\n destParams.partner = t.paramPartner;\\n destParams.feeBps = t.paramFeeBps;\\n destParams.slippageBps = t.paramSlippageBps;\\n destParams.recipient = t.paramRecipient;\\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\\n // the same address as on this chain\\n destParams.tokenIn = t.token;\\n destParams.tokenOut = stream.readAddress();\\n destParams.amountOut = stream.readUint256();\\n destParams.deadline = t.paramDeadline;\\n destParams.commands = stream.readBytes();\\n params.payload = abi.encode(destParams);\\n }\\n\\n if (t.token != t.paramTokenIn) {\\n if (params.payload.length == 0) {\\n // If the tokens are being delivered directly to the recipient without a second\\n // WarpLink engage, the fee is charged on this chain\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibStarVault.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n }\\n\\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\\n\\n if (t.token != address(0)) {\\n if (t.payer != address(this)) {\\n if (t.usePermit == 1) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n t.payer,\\n address(this),\\n (uint160)(t.amount),\\n t.token\\n );\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\\n }\\n\\n // Update the payer to this contract\\n // TODO: Is this value ever read?\\n t.payer = address(this);\\n }\\n\\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\\n IERC20(t.token).forceApprove(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\\n t.amount\\n );\\n }\\n\\n t.jumped = 1;\\n\\n // Swap on the composer if there is a payload, else the router\\n IStargateRouter(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\\n ).swap{\\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\\n }({\\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\\n // more on the other chain. It also assumes the tokens are of nearly equal value\\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: params.dstGasForCall,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n // NOTE: This assumes the contract is deployed at the same address on every chain.\\n // If this is not the case, a new param needs to be added with the next WarpLink address\\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\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\\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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function warpLinkEngagePermit(\\n Params calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n TransientState memory t;\\n t.paramPartner = params.partner;\\n t.paramFeeBps = params.feeBps;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.usePermit = 1;\\n\\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 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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0xafd9df86ea5bc03ea83d33890bbbe7e383f84bec96e5b67dd99e7d717bc9bcb3\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\\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 error InvalidSgReceiverSender();\\n error InvalidSgReceiveSrcAddress();\\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 calldata params) external payable;\\n\\n function warpLinkEngagePermit(\\n Params calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n}\\n\",\"keccak256\":\"0x0eff4788d9f45d72b6a05f34f1e8236a6f9d76a4778396d9a53c66ec04ebf726\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IStargateReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\n\\ninterface IStargateReceiver {\\n function sgReceive(\\n uint16 _srcChainId, // the remote chainId sending the tokens\\n bytes memory _srcAddress, // the remote Bridge address\\n uint256 _nonce,\\n address _token, // the token contract on the local chain\\n uint256 amountLD, // the qty of local _token contract tokens\\n bytes memory payload\\n ) external;\\n}\\n\",\"keccak256\":\"0x7fd06c09139156a4f09a77eac28e453a1d2041a8cf01a108fc875c65192cb637\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50615c3880620000216000396000f3fe6080604052600436106100345760003560e01c8063a703fc4014610039578063ab8236f31461004e578063dcc455511461006e575b600080fd5b61004c610047366004615184565b610081565b005b34801561005a57600080fd5b5061004c610069366004615368565b6106c6565b61004c61007c366004615405565b6109ac565b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152906100fd9084018461543a565b73ffffffffffffffffffffffffffffffffffffffff1681526101256040840160208501615457565b61ffff16602082015261013e6060840160408501615457565b61ffff1660c0820152610157608084016060850161543a565b73ffffffffffffffffffffffffffffffffffffffff16604082015261018260a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0840135608083015260e084013560a08301526101c490840160408501615457565b61ffff1660c08201526101df61012084016101008501615488565b65ffffffffffff1660e082015260c083013561010082015261020760a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff9081166101408301526001610160830152336101208301819052346101a08401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e08101909152921691632b67b570919080606081018061028a60a08b0160808c0161543a565b73ffffffffffffffffffffffffffffffffffffffff908116825260c08b01351660208201526040016102c46101208b016101008c01615488565b65ffffffffffff908116825289351660209182015290825230908201526040016102f661012089016101008a01615488565b65ffffffffffff16905261030d60208701876154a5565b6040518563ffffffff1660e01b815260040161032c9493929190615511565b600060405180830381600087803b15801561034657600080fd5b505af115801561035a573d6000803e3d6000fd5b5050505060006103ae8480610120019061037491906154a5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f4192505050565b90506103ba8183610f5b565b610100810151610140820151919350906103da60c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043e576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61045b60e08701356104566060890160408a01615457565b611140565b821015610494576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361018001516001036104a957505050505050565b6104e86104b9602088018861543a565b6104c960c0890160a08a0161543a565b6104d960408a0160208b01615457565b61ffff168960e001358661116e565b915081600003610524576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661059a5761054f608087016060880161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610594573d6000803e3d6000fd5b506105cb565b6105cb6105ad608088016060890161543a565b73ffffffffffffffffffffffffffffffffffffffff83169084611227565b6101a084015115610609576101a0840151604051339180156108fc02916000818181858888f19350505050158015610607573d6000803e3d6000fd5b505b61061960c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff1661063f60a088016080890161543a565b73ffffffffffffffffffffffffffffffffffffffff16610662602089018961543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c00135866040516106b6929190918252602082015260400190565b60405180910390a4505050505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461078d576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906107a39190615662565b608081015190915073ffffffffffffffffffffffffffffffffffffffff166107ca57600094505b3063dcc4555173ffffffffffffffffffffffffffffffffffffffff8716156107f35760006107f5565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff1681526020018561012001518152506040518363ffffffff1660e01b81526004016108e191906157aa565b6000604051808303818588803b1580156108fa57600080fd5b505af19350505050801561090c575060015b6109a25773ffffffffffffffffffffffffffffffffffffffff851661097b57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610975573d6000803e3d6000fd5b506109a2565b60608101516109a29073ffffffffffffffffffffffffffffffffffffffff87169086611227565b5050505050505050565b6109be61012082016101008301615488565b65ffffffffffff164211156109ff576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082015290610a7b9083018361543a565b73ffffffffffffffffffffffffffffffffffffffff168152610aa36040830160208401615457565b61ffff166020820152610abc6060830160408401615457565b61ffff1660c0820152610ad5608083016060840161543a565b73ffffffffffffffffffffffffffffffffffffffff166040820152610b0060a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0830135608083015260e083013560a0830152610b4290830160408401615457565b61ffff1660c0820152610b5d61012083016101008401615488565b65ffffffffffff1660e082015260c0820135610100820152610b8560a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff166101408201526000610bb360a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1603610c2c578160c00135341015610c0c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c1a60c0830135346158dc565b6101a082015230610120820152610c3b565b33610120820152346101a08201525b6000610c4e6103746101208501856154a5565b9050610c5a8183610f5b565b61010081015161014082015191935090610c7a60c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cde576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cf660e08601356104566060880160408901615457565b821015610d2f576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836101800151600103610d43575050505050565b610d82610d53602087018761543a565b610d6360c0880160a0890161543a565b610d736040890160208a01615457565b61ffff168860e001358661116e565b915081600003610dbe576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e3457610de9608086016060870161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610e2e573d6000803e3d6000fd5b50610e47565b610e476105ad608087016060880161543a565b6101a084015115610e85576101a0840151604051339180156108fc02916000818181858888f19350505050158015610e83573d6000803e3d6000fd5b505b610e9560c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ebb60a087016080880161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ede602088018861543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38860c0013586604051610f32929190918252602082015260400190565b60405180910390a45050505050565b604080518082019091528181528151909101602082015290565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000610fde8480516001018051915290565b60ff16905060005b818110156111345760006110008680516001018051915290565b60ff1690506001810361101d5761101685611300565b9450611121565b6002810361102e57611016856114d0565b600381036110405761101686866117f2565b60048103611052576110168686611e2a565b600581036110645761101686866121c1565b600681036110765761101686866129e3565b60078103611088576110168686612f20565b6008810361109a576110168686613471565b600981036110ef576110ad6001846158dc565b82146110e5576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61101686866138fd565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061112c816158ef565b915050610fe6565b50829150505b92915050565b600061271061114f8382615927565b61115d9061ffff1685615942565b6111679190615988565b9392505050565b60006107d08411156111b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156111c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156111fd5760646032840204611200565b60005b9050808303838214611218576112188a8a8484614125565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112fb9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526141ed565b505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140808201839052610160820183905261018082018390526101a0820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff16156113e5576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014611439576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b1580156114b057600080fd5b505af11580156114c4573d6000803e3d6000fd5b50959695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146115be576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff811630148015906115ec57306101208601525b6000610140860152801561175a578461016001516001036116b057600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b5050505061175a565b82546101008601516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015611734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175891906159c3565b505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916117b79160040190815260200190565b600060405180830381600087803b1580156117d157600080fd5b505af11580156117e5573d6000803e3d6000fd5b5096979650505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff166118b5576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff909116036119aa576119a5816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b611ad8565b826101600151600103611a90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015611a7357600080fd5b505af1158015611a87573d6000803e3d6000fd5b50505050611ad0565b611ad0836101200151826020015185610100015186610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208401525b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151611b7e57905b606083015161010086015161ffff6127109283031691840290820290810190830281611bac57611bac615959565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c469190615a53565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8560400151611c7c57876101000151611c7f565b60005b8660400151611c8f576000611c96565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015611d0057600080fd5b505af1158015611d14573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190615a53565b905081811080611dca5750610100870151611dc79083615a6c565b81105b15611e01576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000611ead8480516001018051915290565b60ff1690506000836101000151905060006002831015611ef9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561218c576000611f146001886158dc565b8210611f205785611f51565b612710611f338b80516002018051915290565b61ffff168a6101000151611f479190615942565b611f519190615988565b905085811115611f8d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f9781876158dc565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610120808201838152610140808401858152610160850186905261018085018690526101a08501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d01511690915290965061203e8b82610f5b565b905080610180015160010361207f576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361209c5780610120015193508061014001519450612170565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614612106576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614612170576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008101516121809087615a6c565b95505050600101611eff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261225660405180606001604052806060815260200160608152602001606081525090565b60006122688580516001018051915290565b60ff169050612278816001615a6c565b67ffffffffffffffff81111561229057612290615202565b6040519080825280602002602001820160405280156122b9578160200160208202803683370190505b5080835261014085015181519091906000906122d7576122d7615a7f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561237057855160140180519087528351612333836001615a6c565b8151811061234357612343615a7f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612314565b5061237b8582614360565b602083015261238a8582614402565b60408301528151805160009190839081106123a7576123a7615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615a53565b9050600061246284604001518761010001518660000151876020015161448b565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff16036124f4576124ef84602001516000815181106124b6576124b6615a7f565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b61265f565b8561016001516001036125fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061256057612560615a7f565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b81526004016125c6949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b50505050612657565b612657866101200151856020015160008151811061261d5761261d615a7f565b602002602001015188610100015189610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208701525b60005b83811015612863576000612677826001615a6c565b905060008660000151828151811061269157612691615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16876000015184815181106126c5576126c5615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106126ef5760006126f2565b60015b90506000600288600001515161270891906158dc565b84106127145730612733565b8760200151838151811061272a5761272a615a7f565b60200260200101515b90508760200151848151811061274b5761274b615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836127925786858151811061278557612785615a7f565b6020026020010151612795565b60005b846127a15760006127bc565b8786815181106127b3576127b3615a7f565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561283c57600080fd5b505af1158015612850573d6000803e3d6000fd5b5050600190950194506126629350505050565b5060008460000151848151811061287c5761287c615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129169190615a53565b9050816001835161292791906158dc565b8151811061293757612937615a7f565b6020026020010151876101000181815250508281108061296557506101008701516129629084615a6c565b81105b1561299c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518051859081106129b0576129b0615a7f565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015261014084015116612afe576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190615a53565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff16109050612c376040518060800160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018761016001518152506146c0565b8015612d1b5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d029190615aae565b91505080612d0f90615ad2565b61010087015250612e03565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def9190615aae565b509050612dfb81615ad2565b610100870152505b612e0b61484f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615a53565b905082811080612ebb5750610100860151612eb89084615a6c565b81105b15612ef2576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a0810191909152612fb560405180606001604052806060815260200160608152602001606081525090565b6000612fc78580516001018051915290565b60ff169050612fd68582614360565b8252612fe28582614360565b60208301528151600090612ff76001846158dc565b8151811061300757613007615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190615a53565b905060005b8381101561337957600081156130e55785516130c86001846158dc565b815181106130d8576130d8615a7f565b60200260200101516130ec565b8761014001515b90508560000151828151811061310457613104615a7f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516080810182526101008d015181526101208d01518416948101949094529184169183018290526101608b015160608401521190613170906146c0565b8260000361318057306101208a01525b60008760200151848151811061319857613198615a7f565b602002602001015190508115613282576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615aae565b9150508061327690615ad2565b6101008c015250613366565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561332e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133529190615aae565b50905061335e81615ad2565b6101008c0152505b61336e61484f565b5050506001016130ab565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156133ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134109190615a53565b90508181108061342e575061010087015161342b9083615a6c565b81105b15613465576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146136fe578461016001516001036136ba577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561369d57600080fd5b505af11580156136b1573d6000803e3d6000fd5b505050506136f6565b6136f68561012001513087610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208601525b60008161379b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137969190615a53565b61379d565b475b9050826137dd576137dd846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166148af9092919063ffffffff16565b61382284608001518560a001518660200151866137fb576000613802565b8961010001515b886040015189606001518c610100015160008b8061381d57508a5b61499f565b6000826138bf5784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ba9190615a53565b6138c1565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506138eb82826158dc565b61010088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526139a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613b31576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff16610100820152845160208082018051909201018652610120820152604051613afc9082906020016157aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613c4357806080015151600003613ba55782516101408401516020850151610100860151613b9e93929161ffff16908061116e565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38660800151876101000151604051613c3a929190918252602082015260400190565b60405180910390a45b613c558360a001518460c00151611140565b8361010001511015613c93576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff918216911615613ecd5761012084015173ffffffffffffffffffffffffffffffffffffffff163014613e1f57836101600151600103613ddb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015613dbe57600080fd5b505af1158015613dd2573d6000803e3d6000fd5b50505050613e17565b613e178461012001513086610100015187610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208501525b613ecd826080015151600014613e355781613ea4565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea49190615b0a565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff1691906148af565b600161018085015260808201515115613ee65780613f55565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f559190615b0a565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff1614613fb457856101a00151613fca565b856101a00151866101000151613fca9190615a6c565b8451602086015160408701516101008a015160c08b0151309190613fef908290611140565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c608001515111614035578d60400151614037565b305b604051602001614072919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b1683526140e29998979695949392600401615b27565b6000604051808303818588803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b505060006101a088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b600061424f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614e9b9092919063ffffffff16565b905080516000148061427057508080602001905181019061427091906159c3565b6112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016111ac565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261435a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611279565b50505050565b60608167ffffffffffffffff81111561437b5761437b615202565b6040519080825280602002602001820160405280156143a4578160200160208202803683370190505b50905060005b828110156143fb57835160140180519085528282815181106143ce576143ce615a7f565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016143aa565b5092915050565b60608167ffffffffffffffff81111561441d5761441d615202565b604051908082528060200260200182016040528015614446578160200160208202803683370190505b50905060005b828110156143fb578351600201805190855282828151811061447057614470615a7f565b61ffff9092166020928302919091019091015260010161444c565b805182516060919067ffffffffffffffff8111156144ab576144ab615202565b6040519080825280602002602001820160405280156144d4578160200160208202803683370190505b50915084826000815181106144eb576144eb615a7f565b60200260200101818152505060005b818110156146b657600085828151811061451657614516615a7f565b602002602001015190506000868360016145309190615a6c565b8151811061454057614540615a7f565b60200260200101519050600089848151811061455e5761455e615a7f565b60200260200101516127106145739190615927565b61ffff16905060008088868151811061458e5761458e615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156145e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146049190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561465f57905b828b0282612710020181848d02028161467a5761467a615959565b049a508a8861468a886001615a6c565b8151811061469a5761469a615a7f565b60209081029190910101525050600190930192506144fa915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361471e576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036148ad576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261493b8482614eb2565b61435a5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526149959085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611279565b61435a84826141ed565b8860ff16600103614acd578715614a58576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015614a3a57600080fd5b505af1158015614a4e573d6000803e3d6000fd5b5050505050614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614a21565b8860ff16600203614c0d578715614b98576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015614b6d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190614b929190615a53565b50614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614b4f565b8860ff16600303614dae578715614c8b576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614b4f565b8015614d05576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614b4f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015614d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b929190615a53565b8860ff16600403614e5e578715614df1576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614a21565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6060614eaa8484600085614f73565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614edc9190615bd3565b6000604051808303816000865af19150503d8060008114614f19576040519150601f19603f3d011682016040523d82523d6000602084013e614f1e565b606091505b5091509150818015614f48575080511580614f48575080806020019051810190614f4891906159c3565b8015614f6a575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b606082471015615005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016111ac565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161502e9190615bd3565b60006040518083038185875af1925050503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b50915091506150818783838761508c565b979650505050505050565b6060831561512257825160000361511b5773ffffffffffffffffffffffffffffffffffffffff85163b61511b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016111ac565b5081614eaa565b614eaa83838151156151375781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac9190615bef565b6000610140828403121561517e57600080fd5b50919050565b6000806040838503121561519757600080fd5b823567ffffffffffffffff808211156151af57600080fd5b6151bb8683870161516b565b935060208501359150808211156151d157600080fd5b508301604081860312156151e457600080fd5b809150509250929050565b61ffff811681146151ff57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561525557615255615202565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156152a2576152a2615202565b604052919050565b600067ffffffffffffffff8211156152c4576152c4615202565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261530157600080fd5b813561531461530f826152aa565b61525b565b81815284602083860101111561532957600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146151ff57600080fd5b60008060008060008060c0878903121561538157600080fd5b863561538c816151ef565b9550602087013567ffffffffffffffff808211156153a957600080fd5b6153b58a838b016152f0565b965060408901359550606089013591506153ce82615346565b9093506080880135925060a088013590808211156153eb57600080fd5b506153f889828a016152f0565b9150509295509295509295565b60006020828403121561541757600080fd5b813567ffffffffffffffff81111561542e57600080fd5b614eaa8482850161516b565b60006020828403121561544c57600080fd5b813561116781615346565b60006020828403121561546957600080fd5b8135611167816151ef565b65ffffffffffff811681146151ff57600080fd5b60006020828403121561549a57600080fd5b813561116781615474565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154da57600080fd5b83018035915067ffffffffffffffff8211156154f557600080fd5b60200191503681900382131561550a57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b80516155de81615346565b919050565b80516155de816151ef565b80516155de81615474565b60005b838110156156145781810151838201526020016155fc565b50506000910152565b600082601f83011261562e57600080fd5b815161563c61530f826152aa565b81815284602083860101111561565157600080fd5b614eaa8260208301602087016155f9565b60006020828403121561567457600080fd5b815167ffffffffffffffff8082111561568c57600080fd5b9083019061014082860312156156a157600080fd5b6156a9615231565b6156b2836155d3565b81526156c0602084016155e3565b60208201526156d1604084016155e3565b60408201526156e2606084016155d3565b60608201526156f3608084016155d3565b608082015261570460a084016155d3565b60a082015260c083015160c082015260e083015160e082015261010061572b8185016155ee565b90820152610120838101518381111561574357600080fd5b61574f8882870161561d565b918301919091525095945050505050565b600081518084526157788160208601602086016155f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526157d160208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516157e8604084018261ffff169052565b50604083015161ffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c083015160e083015260e08301516101008181850152808501519150506101206158938185018365ffffffffffff169052565b840151610140848101529050614eaa610160840182615760565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561113a5761113a6158ad565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615920576159206158ad565b5060010190565b61ffff8281168282160390808211156143fb576143fb6158ad565b808202811582820484141761113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156159d557600080fd5b8151801515811461116757600080fd5b80516dffffffffffffffffffffffffffff811681146155de57600080fd5b600080600060608486031215615a1857600080fd5b615a21846159e5565b9250615a2f602085016159e5565b9150604084015163ffffffff81168114615a4857600080fd5b809150509250925092565b600060208284031215615a6557600080fd5b5051919050565b8082018082111561113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215615ac157600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b0357615b036158ad565b5060000390565b600060208284031215615b1c57600080fd5b815161116781615346565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615b9a610180840182615760565b905082810360e0840152615bae8186615760565b9050828103610100840152615bc38185615760565b9c9b505050505050505050505050565b60008251615be58184602087016155f9565b9190910192915050565b602081526000611167602083018461576056fea26469706673582212202ce6a8f21a153c83c150806f9ce2e260656621d27c2de20b34fdaa1dbce5be3f64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c8063a703fc4014610039578063ab8236f31461004e578063dcc455511461006e575b600080fd5b61004c610047366004615184565b610081565b005b34801561005a57600080fd5b5061004c610069366004615368565b6106c6565b61004c61007c366004615405565b6109ac565b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152906100fd9084018461543a565b73ffffffffffffffffffffffffffffffffffffffff1681526101256040840160208501615457565b61ffff16602082015261013e6060840160408501615457565b61ffff1660c0820152610157608084016060850161543a565b73ffffffffffffffffffffffffffffffffffffffff16604082015261018260a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0840135608083015260e084013560a08301526101c490840160408501615457565b61ffff1660c08201526101df61012084016101008501615488565b65ffffffffffff1660e082015260c083013561010082015261020760a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff9081166101408301526001610160830152336101208301819052346101a08401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e08101909152921691632b67b570919080606081018061028a60a08b0160808c0161543a565b73ffffffffffffffffffffffffffffffffffffffff908116825260c08b01351660208201526040016102c46101208b016101008c01615488565b65ffffffffffff908116825289351660209182015290825230908201526040016102f661012089016101008a01615488565b65ffffffffffff16905261030d60208701876154a5565b6040518563ffffffff1660e01b815260040161032c9493929190615511565b600060405180830381600087803b15801561034657600080fd5b505af115801561035a573d6000803e3d6000fd5b5050505060006103ae8480610120019061037491906154a5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f4192505050565b90506103ba8183610f5b565b610100810151610140820151919350906103da60c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043e576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61045b60e08701356104566060890160408a01615457565b611140565b821015610494576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361018001516001036104a957505050505050565b6104e86104b9602088018861543a565b6104c960c0890160a08a0161543a565b6104d960408a0160208b01615457565b61ffff168960e001358661116e565b915081600003610524576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661059a5761054f608087016060880161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610594573d6000803e3d6000fd5b506105cb565b6105cb6105ad608088016060890161543a565b73ffffffffffffffffffffffffffffffffffffffff83169084611227565b6101a084015115610609576101a0840151604051339180156108fc02916000818181858888f19350505050158015610607573d6000803e3d6000fd5b505b61061960c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff1661063f60a088016080890161543a565b73ffffffffffffffffffffffffffffffffffffffff16610662602089018961543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c00135866040516106b6929190918252602082015260400190565b60405180910390a4505050505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461078d576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906107a39190615662565b608081015190915073ffffffffffffffffffffffffffffffffffffffff166107ca57600094505b3063dcc4555173ffffffffffffffffffffffffffffffffffffffff8716156107f35760006107f5565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff1681526020018561012001518152506040518363ffffffff1660e01b81526004016108e191906157aa565b6000604051808303818588803b1580156108fa57600080fd5b505af19350505050801561090c575060015b6109a25773ffffffffffffffffffffffffffffffffffffffff851661097b57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610975573d6000803e3d6000fd5b506109a2565b60608101516109a29073ffffffffffffffffffffffffffffffffffffffff87169086611227565b5050505050505050565b6109be61012082016101008301615488565b65ffffffffffff164211156109ff576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082015290610a7b9083018361543a565b73ffffffffffffffffffffffffffffffffffffffff168152610aa36040830160208401615457565b61ffff166020820152610abc6060830160408401615457565b61ffff1660c0820152610ad5608083016060840161543a565b73ffffffffffffffffffffffffffffffffffffffff166040820152610b0060a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0830135608083015260e083013560a0830152610b4290830160408401615457565b61ffff1660c0820152610b5d61012083016101008401615488565b65ffffffffffff1660e082015260c0820135610100820152610b8560a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff166101408201526000610bb360a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1603610c2c578160c00135341015610c0c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c1a60c0830135346158dc565b6101a082015230610120820152610c3b565b33610120820152346101a08201525b6000610c4e6103746101208501856154a5565b9050610c5a8183610f5b565b61010081015161014082015191935090610c7a60c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cde576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cf660e08601356104566060880160408901615457565b821015610d2f576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836101800151600103610d43575050505050565b610d82610d53602087018761543a565b610d6360c0880160a0890161543a565b610d736040890160208a01615457565b61ffff168860e001358661116e565b915081600003610dbe576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e3457610de9608086016060870161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610e2e573d6000803e3d6000fd5b50610e47565b610e476105ad608087016060880161543a565b6101a084015115610e85576101a0840151604051339180156108fc02916000818181858888f19350505050158015610e83573d6000803e3d6000fd5b505b610e9560c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ebb60a087016080880161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ede602088018861543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38860c0013586604051610f32929190918252602082015260400190565b60405180910390a45050505050565b604080518082019091528181528151909101602082015290565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000610fde8480516001018051915290565b60ff16905060005b818110156111345760006110008680516001018051915290565b60ff1690506001810361101d5761101685611300565b9450611121565b6002810361102e57611016856114d0565b600381036110405761101686866117f2565b60048103611052576110168686611e2a565b600581036110645761101686866121c1565b600681036110765761101686866129e3565b60078103611088576110168686612f20565b6008810361109a576110168686613471565b600981036110ef576110ad6001846158dc565b82146110e5576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61101686866138fd565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061112c816158ef565b915050610fe6565b50829150505b92915050565b600061271061114f8382615927565b61115d9061ffff1685615942565b6111679190615988565b9392505050565b60006107d08411156111b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156111c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156111fd5760646032840204611200565b60005b9050808303838214611218576112188a8a8484614125565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112fb9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526141ed565b505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140808201839052610160820183905261018082018390526101a0820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff16156113e5576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014611439576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b1580156114b057600080fd5b505af11580156114c4573d6000803e3d6000fd5b50959695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146115be576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff811630148015906115ec57306101208601525b6000610140860152801561175a578461016001516001036116b057600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b5050505061175a565b82546101008601516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015611734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175891906159c3565b505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916117b79160040190815260200190565b600060405180830381600087803b1580156117d157600080fd5b505af11580156117e5573d6000803e3d6000fd5b5096979650505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff166118b5576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff909116036119aa576119a5816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b611ad8565b826101600151600103611a90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015611a7357600080fd5b505af1158015611a87573d6000803e3d6000fd5b50505050611ad0565b611ad0836101200151826020015185610100015186610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208401525b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151611b7e57905b606083015161010086015161ffff6127109283031691840290820290810190830281611bac57611bac615959565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c469190615a53565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8560400151611c7c57876101000151611c7f565b60005b8660400151611c8f576000611c96565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015611d0057600080fd5b505af1158015611d14573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190615a53565b905081811080611dca5750610100870151611dc79083615a6c565b81105b15611e01576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000611ead8480516001018051915290565b60ff1690506000836101000151905060006002831015611ef9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561218c576000611f146001886158dc565b8210611f205785611f51565b612710611f338b80516002018051915290565b61ffff168a6101000151611f479190615942565b611f519190615988565b905085811115611f8d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f9781876158dc565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610120808201838152610140808401858152610160850186905261018085018690526101a08501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d01511690915290965061203e8b82610f5b565b905080610180015160010361207f576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361209c5780610120015193508061014001519450612170565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614612106576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614612170576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008101516121809087615a6c565b95505050600101611eff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261225660405180606001604052806060815260200160608152602001606081525090565b60006122688580516001018051915290565b60ff169050612278816001615a6c565b67ffffffffffffffff81111561229057612290615202565b6040519080825280602002602001820160405280156122b9578160200160208202803683370190505b5080835261014085015181519091906000906122d7576122d7615a7f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561237057855160140180519087528351612333836001615a6c565b8151811061234357612343615a7f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612314565b5061237b8582614360565b602083015261238a8582614402565b60408301528151805160009190839081106123a7576123a7615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615a53565b9050600061246284604001518761010001518660000151876020015161448b565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff16036124f4576124ef84602001516000815181106124b6576124b6615a7f565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b61265f565b8561016001516001036125fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061256057612560615a7f565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b81526004016125c6949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b50505050612657565b612657866101200151856020015160008151811061261d5761261d615a7f565b602002602001015188610100015189610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208701525b60005b83811015612863576000612677826001615a6c565b905060008660000151828151811061269157612691615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16876000015184815181106126c5576126c5615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106126ef5760006126f2565b60015b90506000600288600001515161270891906158dc565b84106127145730612733565b8760200151838151811061272a5761272a615a7f565b60200260200101515b90508760200151848151811061274b5761274b615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836127925786858151811061278557612785615a7f565b6020026020010151612795565b60005b846127a15760006127bc565b8786815181106127b3576127b3615a7f565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561283c57600080fd5b505af1158015612850573d6000803e3d6000fd5b5050600190950194506126629350505050565b5060008460000151848151811061287c5761287c615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129169190615a53565b9050816001835161292791906158dc565b8151811061293757612937615a7f565b6020026020010151876101000181815250508281108061296557506101008701516129629084615a6c565b81105b1561299c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518051859081106129b0576129b0615a7f565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015261014084015116612afe576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190615a53565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff16109050612c376040518060800160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018761016001518152506146c0565b8015612d1b5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d029190615aae565b91505080612d0f90615ad2565b61010087015250612e03565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def9190615aae565b509050612dfb81615ad2565b610100870152505b612e0b61484f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615a53565b905082811080612ebb5750610100860151612eb89084615a6c565b81105b15612ef2576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a0810191909152612fb560405180606001604052806060815260200160608152602001606081525090565b6000612fc78580516001018051915290565b60ff169050612fd68582614360565b8252612fe28582614360565b60208301528151600090612ff76001846158dc565b8151811061300757613007615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190615a53565b905060005b8381101561337957600081156130e55785516130c86001846158dc565b815181106130d8576130d8615a7f565b60200260200101516130ec565b8761014001515b90508560000151828151811061310457613104615a7f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516080810182526101008d015181526101208d01518416948101949094529184169183018290526101608b015160608401521190613170906146c0565b8260000361318057306101208a01525b60008760200151848151811061319857613198615a7f565b602002602001015190508115613282576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615aae565b9150508061327690615ad2565b6101008c015250613366565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561332e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133529190615aae565b50905061335e81615ad2565b6101008c0152505b61336e61484f565b5050506001016130ab565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156133ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134109190615a53565b90508181108061342e575061010087015161342b9083615a6c565b81105b15613465576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146136fe578461016001516001036136ba577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561369d57600080fd5b505af11580156136b1573d6000803e3d6000fd5b505050506136f6565b6136f68561012001513087610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208601525b60008161379b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137969190615a53565b61379d565b475b9050826137dd576137dd846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166148af9092919063ffffffff16565b61382284608001518560a001518660200151866137fb576000613802565b8961010001515b886040015189606001518c610100015160008b8061381d57508a5b61499f565b6000826138bf5784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ba9190615a53565b6138c1565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506138eb82826158dc565b61010088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526139a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613b31576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff16610100820152845160208082018051909201018652610120820152604051613afc9082906020016157aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613c4357806080015151600003613ba55782516101408401516020850151610100860151613b9e93929161ffff16908061116e565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38660800151876101000151604051613c3a929190918252602082015260400190565b60405180910390a45b613c558360a001518460c00151611140565b8361010001511015613c93576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff918216911615613ecd5761012084015173ffffffffffffffffffffffffffffffffffffffff163014613e1f57836101600151600103613ddb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015613dbe57600080fd5b505af1158015613dd2573d6000803e3d6000fd5b50505050613e17565b613e178461012001513086610100015187610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208501525b613ecd826080015151600014613e355781613ea4565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea49190615b0a565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff1691906148af565b600161018085015260808201515115613ee65780613f55565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f559190615b0a565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff1614613fb457856101a00151613fca565b856101a00151866101000151613fca9190615a6c565b8451602086015160408701516101008a015160c08b0151309190613fef908290611140565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c608001515111614035578d60400151614037565b305b604051602001614072919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b1683526140e29998979695949392600401615b27565b6000604051808303818588803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b505060006101a088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b600061424f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614e9b9092919063ffffffff16565b905080516000148061427057508080602001905181019061427091906159c3565b6112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016111ac565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261435a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611279565b50505050565b60608167ffffffffffffffff81111561437b5761437b615202565b6040519080825280602002602001820160405280156143a4578160200160208202803683370190505b50905060005b828110156143fb57835160140180519085528282815181106143ce576143ce615a7f565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016143aa565b5092915050565b60608167ffffffffffffffff81111561441d5761441d615202565b604051908082528060200260200182016040528015614446578160200160208202803683370190505b50905060005b828110156143fb578351600201805190855282828151811061447057614470615a7f565b61ffff9092166020928302919091019091015260010161444c565b805182516060919067ffffffffffffffff8111156144ab576144ab615202565b6040519080825280602002602001820160405280156144d4578160200160208202803683370190505b50915084826000815181106144eb576144eb615a7f565b60200260200101818152505060005b818110156146b657600085828151811061451657614516615a7f565b602002602001015190506000868360016145309190615a6c565b8151811061454057614540615a7f565b60200260200101519050600089848151811061455e5761455e615a7f565b60200260200101516127106145739190615927565b61ffff16905060008088868151811061458e5761458e615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156145e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146049190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561465f57905b828b0282612710020181848d02028161467a5761467a615959565b049a508a8861468a886001615a6c565b8151811061469a5761469a615a7f565b60209081029190910101525050600190930192506144fa915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361471e576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036148ad576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261493b8482614eb2565b61435a5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526149959085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611279565b61435a84826141ed565b8860ff16600103614acd578715614a58576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015614a3a57600080fd5b505af1158015614a4e573d6000803e3d6000fd5b5050505050614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614a21565b8860ff16600203614c0d578715614b98576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015614b6d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190614b929190615a53565b50614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614b4f565b8860ff16600303614dae578715614c8b576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614b4f565b8015614d05576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614b4f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015614d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b929190615a53565b8860ff16600403614e5e578715614df1576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614a21565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6060614eaa8484600085614f73565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614edc9190615bd3565b6000604051808303816000865af19150503d8060008114614f19576040519150601f19603f3d011682016040523d82523d6000602084013e614f1e565b606091505b5091509150818015614f48575080511580614f48575080806020019051810190614f4891906159c3565b8015614f6a575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b606082471015615005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016111ac565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161502e9190615bd3565b60006040518083038185875af1925050503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b50915091506150818783838761508c565b979650505050505050565b6060831561512257825160000361511b5773ffffffffffffffffffffffffffffffffffffffff85163b61511b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016111ac565b5081614eaa565b614eaa83838151156151375781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac9190615bef565b6000610140828403121561517e57600080fd5b50919050565b6000806040838503121561519757600080fd5b823567ffffffffffffffff808211156151af57600080fd5b6151bb8683870161516b565b935060208501359150808211156151d157600080fd5b508301604081860312156151e457600080fd5b809150509250929050565b61ffff811681146151ff57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561525557615255615202565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156152a2576152a2615202565b604052919050565b600067ffffffffffffffff8211156152c4576152c4615202565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261530157600080fd5b813561531461530f826152aa565b61525b565b81815284602083860101111561532957600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146151ff57600080fd5b60008060008060008060c0878903121561538157600080fd5b863561538c816151ef565b9550602087013567ffffffffffffffff808211156153a957600080fd5b6153b58a838b016152f0565b965060408901359550606089013591506153ce82615346565b9093506080880135925060a088013590808211156153eb57600080fd5b506153f889828a016152f0565b9150509295509295509295565b60006020828403121561541757600080fd5b813567ffffffffffffffff81111561542e57600080fd5b614eaa8482850161516b565b60006020828403121561544c57600080fd5b813561116781615346565b60006020828403121561546957600080fd5b8135611167816151ef565b65ffffffffffff811681146151ff57600080fd5b60006020828403121561549a57600080fd5b813561116781615474565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154da57600080fd5b83018035915067ffffffffffffffff8211156154f557600080fd5b60200191503681900382131561550a57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b80516155de81615346565b919050565b80516155de816151ef565b80516155de81615474565b60005b838110156156145781810151838201526020016155fc565b50506000910152565b600082601f83011261562e57600080fd5b815161563c61530f826152aa565b81815284602083860101111561565157600080fd5b614eaa8260208301602087016155f9565b60006020828403121561567457600080fd5b815167ffffffffffffffff8082111561568c57600080fd5b9083019061014082860312156156a157600080fd5b6156a9615231565b6156b2836155d3565b81526156c0602084016155e3565b60208201526156d1604084016155e3565b60408201526156e2606084016155d3565b60608201526156f3608084016155d3565b608082015261570460a084016155d3565b60a082015260c083015160c082015260e083015160e082015261010061572b8185016155ee565b90820152610120838101518381111561574357600080fd5b61574f8882870161561d565b918301919091525095945050505050565b600081518084526157788160208601602086016155f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526157d160208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516157e8604084018261ffff169052565b50604083015161ffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c083015160e083015260e08301516101008181850152808501519150506101206158938185018365ffffffffffff169052565b840151610140848101529050614eaa610160840182615760565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561113a5761113a6158ad565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615920576159206158ad565b5060010190565b61ffff8281168282160390808211156143fb576143fb6158ad565b808202811582820484141761113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156159d557600080fd5b8151801515811461116757600080fd5b80516dffffffffffffffffffffffffffff811681146155de57600080fd5b600080600060608486031215615a1857600080fd5b615a21846159e5565b9250615a2f602085016159e5565b9150604084015163ffffffff81168114615a4857600080fd5b809150509250925092565b600060208284031215615a6557600080fd5b5051919050565b8082018082111561113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215615ac157600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b0357615b036158ad565b5060000390565b600060208284031215615b1c57600080fd5b815161116781615346565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615b9a610180840182615760565b905082810360e0840152615bae8186615760565b9050828103610100840152615bc38185615760565b9c9b505050505050505050505050565b60008251615be58184602087016155f9565b9190910192915050565b602081526000611167602083018461576056fea26469706673582212202ce6a8f21a153c83c150806f9ce2e260656621d27c2de20b34fdaa1dbce5be3f64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/avalanche/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json b/packages/hardhat/deployments/avalanche/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json new file mode 100644 index 00000000..cf1aa121 --- /dev/null +++ b/packages/hardhat/deployments/avalanche/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json @@ -0,0 +1,170 @@ +{ + "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" + }, + "@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * Perform the swap with tokens already moved to this contract\n */\n function curveExactInputSingleInternal(\n ExactInputSingleParams calldata params\n ) internal returns (uint256 amountOut) {\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 LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n useEth: params.tokenIn == address(0) || isToEth,\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function curveExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (params.tokenIn == address(0)) {\n revert PermitForEthToken();\n }\n\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 return curveExactInputSingleInternal(params);\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\n }\n\n return curveExactInputSingleInternal(params);\n }\n}\n" + }, + "contracts/facets/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract Stargate is IStargate {\n using SafeERC20 for IERC20;\n\n /**\n * Jump tokens with Stargate with input tokens already moved to this contract\n */\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.token,\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n // NOTE: This lookup is spending 319 gas\n IStargateRouter stargateRouter = IStargateRouter(\n LibWarp.state().stargateComposer.stargateRouter()\n );\n\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\n\n unchecked {\n stargateRouter.swap{value: msg.value}({\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\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\n }\n }\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable {\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.token,\n amount: 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 // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n uint160(params.amountIn),\n params.token\n );\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\n // Transfer tokens from the sender to this contract\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n address(0),\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n unchecked {\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\n _dstChainId: params.dstChainId,\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * NOTE: The tokens must already have been moved to the first pool\n */\n function uniswapV2LikeExactInputSingleInternal(\n ExactInputSingleParams memory params\n ) internal returns (uint256 amountOut) {\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : params.tokenIn,\n isToEth ? address(0) : params.tokenOut,\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\n }\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 the pool\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pool,\n (uint160)(params.amountIn),\n params.tokenIn\n );\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputInternal(\n ExactInputParams calldata params\n ) internal returns (uint256 amountOut) {\n LibWarp.State storage s = LibWarp.state();\n\n address[] memory tokens = params.tokens;\n uint256 poolLength = params.pools.length;\n bool isFromEth = tokens[0] == address(0);\n bool isToEth = tokens[poolLength] == address(0);\n\n if (isFromEth) {\n tokens[0] = address(s.weth);\n }\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : tokens[0],\n isToEth ? address(0) : tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\n } else {\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\n }\n\n return uniswapV2LikeExactInputInternal(params);\n }\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n // Permit tokens / set allowance\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n\n return uniswapV2LikeExactInputInternal(params);\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 {LibStarVault} from '../libraries/LibStarVault.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\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /**\n * NOTE: The tokens must already have been transferred to the pool\n */\n function uniswapV2ExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n address pair\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address tokenIn = params.tokenIn == address(0) ? address(s.weth) : params.tokenIn;\n address tokenOut = params.tokenOut == address(0) ? address(s.weth) : params.tokenOut;\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (tokenIn > 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 InsufficientOutputAmount();\n }\n\n bool zeroForOne = tokenIn < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.tokenOut == address(0)) {\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn == address(0) ? address(s.weth) : params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\n if (params.tokenIn == address(0)) {\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(address(s.weth)).safeTransfer(pair, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, pair, params.amountIn);\n }\n\n return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\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 return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n /**\n * NOTE: The tokens must already have been transferred to the first pool\n *\n * The path should be rewritten so address(0) is replaced by the WETH address\n */\n function uniswapV2ExactInputInternal(\n ExactInputParams calldata params,\n address[] memory path,\n address[] memory pairs,\n uint256[] memory amounts\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\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 = path[index] < path[indexPlusOne] ? true : false;\n address to = index < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH. 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(path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.path[0],\n params.path[pathLengthMinusOne],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[0] == address(0)) {\n // From ETH\n path[0] = address(s.weth);\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\n }\n\n if (params.path[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer WETH tokens to the first pool\n IERC20(path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n IERC20(path[0]).safeTransferFrom(msg.sender, pairs[0], params.amountIn);\n }\n\n return uniswapV2ExactInputInternal(params, path, pairs, amounts);\n }\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: 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 return uniswapV2ExactInputInternal(params, path, pairs, amounts);\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 if (callback.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n } else {\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\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 /**\n * NOTE: None of these arguments can be trusted\n */\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * KyperSwap V2 callback\n * NOTE: None of these arguments can be trusted\n */\n function swapCallback(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 {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n bool isFromEth = params.tokenIn == address(0);\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\n\n address tokenOut = params.tokenOut == address(0)\n ? address(LibWarp.state().weth)\n : params.tokenOut;\n\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\n\n bool zeroForOne = tokenIn < tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: tokenIn,\n amount: params.amountIn,\n usePermit: usePermit\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokenOut == address(0)) {\n // To ETH, unwrap WETH\n // TODO: This is read twice. Compare gas usage\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH, wrap it\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\n }\n\n function uniswapV3LikeExactInputInternal(\n ExactInputParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n uint256 poolLength = params.pools.length;\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\n address[] memory tokens = params.tokens;\n\n if (params.tokens[0] == address(0)) {\n tokens[0] = address(LibWarp.state().weth);\n }\n\n if (params.tokens[poolLength] == address(0)) {\n tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: payer,\n token: tokens[index],\n amount: amountOut,\n usePermit: usePermit\n })\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokens[poolLength] == address(0)) {\n // To ETH, unwrap\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.tokens[0],\n params.tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH, wrap it\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n }\n\n return uniswapV3LikeExactInputInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputInternal(params, 1);\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 {LibStarVault} from '../libraries/LibStarVault.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';\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\n bytes payload;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n address paramTokenIn;\n uint256 paramAmountIn;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint48 paramDeadline;\n uint256 amount;\n address payer;\n address token;\n /**\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\n */\n uint256 usePermit;\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 if (t.usePermit == 1) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\n }\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 if (t.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\n }\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(\n t.payer,\n params.pools[0],\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\n }\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({\n payer: t.payer,\n token: t.token,\n amount: t.amount,\n usePermit: t.usePermit\n })\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({\n payer: t.payer,\n token: tokenIn,\n amount: t.amount,\n usePermit: t.usePermit\n })\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\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 useEth: isFromEth || isToEth,\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 * Cross-chain callback from Stargate\n *\n * The tokens have already been received by this contract, `t.payer` is set to this contract\n * before `sgReceive` is called by the router.\n *\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\n * same message more than once.\n *\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\n * Stargate composer be compromised, an attacker can drain this contract.\n *\n * If the payload can not be decoded, tokens are left in this contract.\n * If execution runs out of gas, tokens are left in this contract.\n *\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\n * to the recipient.\n *\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\n */\n function sgReceive(\n uint16, // _srcChainId\n bytes memory _srcAddress,\n uint256, // _nonce\n address _token,\n uint256 amountLD,\n bytes memory payload\n ) external {\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\n revert InvalidSgReceiverSender();\n }\n\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\n // From https://ethereum.stackexchange.com/a/50528\n address srcAddress;\n\n assembly {\n srcAddress := mload(add(_srcAddress, 20))\n }\n\n if (srcAddress != address(this)) {\n // NOTE: This assumes that this contract is deployed at the same address on every chain\n revert InvalidSgReceiveSrcAddress();\n }\n\n Params memory params = abi.decode(payload, (Params));\n\n if (params.tokenIn == address(0)) {\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\n // otherwise because `_token` may be different on this chain\n _token = address(0);\n }\n\n try\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\n Params({\n partner: params.partner,\n feeBps: params.feeBps,\n slippageBps: params.slippageBps,\n recipient: params.recipient,\n tokenIn: _token,\n tokenOut: params.tokenOut,\n amountIn: amountLD,\n amountOut: params.amountOut,\n deadline: params.deadline,\n commands: params.commands\n })\n )\n {} catch {\n // Refund tokens to the recipient\n if (_token == address(0)) {\n payable(params.recipient).transfer(amountLD);\n } else {\n IERC20(_token).safeTransfer(params.recipient, amountLD);\n }\n }\n }\n\n /**\n * Jump to another chain using the Stargate bridge\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\n * in this function.\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 * - dstGasForCall (uint32)\n * - tokenOut (address) when `dstGasForCall` > 0\n * - amountOut (uint256) when `dstGasForCall` > 0\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n params.dstGasForCall = stream.readUint32();\n\n if (params.dstGasForCall > 0) {\n // NOTE: `amountIn` is left as zero\n Params memory destParams;\n destParams.partner = t.paramPartner;\n destParams.feeBps = t.paramFeeBps;\n destParams.slippageBps = t.paramSlippageBps;\n destParams.recipient = t.paramRecipient;\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\n // the same address as on this chain\n destParams.tokenIn = t.token;\n destParams.tokenOut = stream.readAddress();\n destParams.amountOut = stream.readUint256();\n destParams.deadline = t.paramDeadline;\n destParams.commands = stream.readBytes();\n params.payload = abi.encode(destParams);\n }\n\n if (t.token != t.paramTokenIn) {\n if (params.payload.length == 0) {\n // If the tokens are being delivered directly to the recipient without a second\n // WarpLink engage, the fee is charged on this chain\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\n // is never charged\n t.amount = LibStarVault.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n }\n\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n t.payer,\n address(this),\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\n\n // Update the payer to this contract\n // TODO: Is this value ever read?\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\n IERC20(t.token).forceApprove(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\n t.amount\n );\n }\n\n t.jumped = 1;\n\n // Swap on the composer if there is a payload, else the router\n IStargateRouter(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\n ).swap{\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\n }({\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\n // more on the other chain. It also assumes the tokens are of nearly equal value\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: params.dstGasForCall,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n // NOTE: This assumes the contract is deployed at the same address on every chain.\n // If this is not the case, a new param needs to be added with the next WarpLink address\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\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\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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable {\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.usePermit = 1;\n\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 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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\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(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy,\n bool use_eth\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\n// Kind 4, uint256s with no return value\n// Example v0.2.15, \"Pool for USDT/BTC/ETH or similar\"\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\ninterface ICurvePoolKind4 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\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/IStargateComposer.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\nimport {IStargateRouter} from './IStargateRouter.sol';\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateComposer is IStargateRouter {\n function stargateRouter() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/IStargateReceiver.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\n\ninterface IStargateReceiver {\n function sgReceive(\n uint16 _srcChainId, // the remote chainId sending the tokens\n bytes memory _srcAddress, // the remote Bridge address\n uint256 _nonce,\n address _token, // the token contract on the local chain\n uint256 amountLD, // the qty of local _token contract tokens\n bytes memory payload\n ) 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n /**\n * A function expecting a permit was used when the input token is ETH\n */\n error PermitForEthToken();\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 curveExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/ILibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibCurve {\n error UnhandledPoolKind();\n}\n" + }, + "contracts/interfaces/ILibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n}\n" + }, + "contracts/interfaces/ILibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n}\n" + }, + "contracts/interfaces/ILibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n}\n" + }, + "contracts/interfaces/IStargate.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\n\ninterface IStargate is ILibStarVault {\n error InsufficientEthValue();\n\n struct JumpTokenParams {\n address token;\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n struct JumpNativeParams {\n /**\n * The amount in is passed to distinguish the amount to bridge from the fee\n */\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable;\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Like is ILibStarVault, ILibWarp {\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 ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Router is ILibStarVault, ILibWarp {\n error EthTransferFailed();\n error ZeroAmountOut();\n error IncorrectEthValue();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\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 error InvalidSgReceiverSender();\n error InvalidSgReceiveSrcAddress();\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 calldata params) external payable;\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable;\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibCurve\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 bool useEth\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 if (useEth) {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\n } else {\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\n }\n } else if (kind == 4) {\n if (underlying) {\n revert UnhandledPoolKind();\n } else {\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * NOTE: Events and errors must be copied to ILibStarVault\n */\nlibrary LibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n\n struct State {\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 uint256 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n /**\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\n * removed to save gas.\n */\n unchecked {\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\n\n assembly {\n s.slot := storagePosition\n }\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 protocolFee\n ) internal {\n State storage s = state();\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit Fee(partner, token, partnerFee, protocolFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint256 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 feeProtocol = feeTotal - feePartner;\n\n if (feeProtocol > 0) {\n registerCollectedFee(partner, token, feePartner, feeProtocol);\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\n/**\n * NOTE: Events and errors must be copied to ILibUniV3Like\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 * Whether to use a permit transfer (0 or 1)\n */\n uint256 usePermit;\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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibWarp\n */\nlibrary LibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateComposer stargateComposer;\n }\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\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/base/Curve.json b/packages/hardhat/deployments/base/Curve.json index b79dbc16..89191ce1 100644 --- a/packages/hardhat/deployments/base/Curve.json +++ b/packages/hardhat/deployments/base/Curve.json @@ -1,5 +1,5 @@ { - "address": "0x84Cd4555CeEA7B0A209232D2E47c316c08bAfDE8", + "address": "0x56880c7B8eE5c4CF8e362bfa4e493B4b6d3245d3", "abi": [ { "inputs": [], @@ -38,6 +38,11 @@ "name": "InsufficientOutputAmount", "type": "error" }, + { + "inputs": [], + "name": "PermitForEthToken", + "type": "error" + }, { "inputs": [], "name": "UnhandledPoolKind", @@ -116,6 +121,97 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "curveExactInputSingle", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -213,7 +309,7 @@ "type": "tuple" } ], - "name": "curveExactInputSingle", + "name": "curveExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -225,28 +321,28 @@ "type": "function" } ], - "transactionHash": "0xd9843afc941ac11643083bff056821ca308a3448c6c48430c0129d98694eba81", + "transactionHash": "0x95ac8f6130c84682186926d3a7a84d660d35f8f35d4b2122c033cf8cec28b371", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x84Cd4555CeEA7B0A209232D2E47c316c08bAfDE8", + "contractAddress": "0x56880c7B8eE5c4CF8e362bfa4e493B4b6d3245d3", "transactionIndex": 4, - "gasUsed": "1361268", + "gasUsed": "1468512", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x84e103eb4277e8105f3aa3b1023e22e91e8c890253358a22e3bc0e804914568f", - "transactionHash": "0xd9843afc941ac11643083bff056821ca308a3448c6c48430c0129d98694eba81", + "blockHash": "0xd581402093671749ffbc16a41f0030f441469f9c091d0b853d9c151d39fe1834", + "transactionHash": "0x95ac8f6130c84682186926d3a7a84d660d35f8f35d4b2122c033cf8cec28b371", "logs": [], - "blockNumber": 5796155, - "cumulativeGasUsed": "1639220", + "blockNumber": 6230701, + "cumulativeGasUsed": "2171668", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 7, - "solcInputHash": "ebf955869df0dfecc3a0eb12547e8afc", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 useEth: params.tokenIn == address(0) || isToEth,\\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0x6d796fc46a41bd9fe76ae989d273f90aa0298f993f5c77cf481f5968fad21474\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\\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\":\"0x88d6dcf171951cf8e3f3488ef5d66a953614ae48926f9ace36d58b095bf9dc84\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506117d5806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b6100366100313660046113ad565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906114ed565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff9091169161066b565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b90890189611506565b6040518563ffffffff1660e01b815260040161026a9493929190611572565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b6103cc856101800151866101a001518760600151348961014001518a61016001518b6000015160008073ffffffffffffffffffffffffffffffffffffffff168e60e0015173ffffffffffffffffffffffffffffffffffffffff1614806103c757508a5b6107df565b60008261046d576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046891906114ed565b61046f565b475b905061047b8282611663565b935061048f86602001518760a00151610cdb565b8410156104c8576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ea8660c00151876101000151886080015161ffff16896020015188610d0b565b93508215610596576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610550576040519150601f19603f3d011682016040523d82523d6000602084013e610555565b606091505b5050905080610590576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506105ca565b6105ca86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610dc49092919063ffffffff16565b85610100015173ffffffffffffffffffffffffffffffffffffffff168660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f389600001518860405161065a929190918252602082015260400190565b60405180910390a450505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106f78482610e1f565b6107d95760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526107cf9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610ee0565b6107d98482610ee0565b50505050565b8860ff1660010361090d578715610898576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b5050505050610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610861565b8860ff16600203610a4d5787156109d8576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156109ad573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109d291906114ed565b50610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df0212490889060840161098f565b8860ff16600303610bee578715610acb576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b90889060840161098f565b8015610b45576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a40161098f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015610bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d291906114ed565b8860ff16600403610c9e578715610c31576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610861565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6000612710610cea8382611676565b610cf89061ffff1685611698565b610d0291906116af565b90505b92915050565b60006107d0841115610d52576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610d64575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610d9a5760646032840204610d9d565b60005b9050808303838214610db557610db58a8a8484610fef565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e1a9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161074d565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e49919061170e565b6000604051808303816000865af19150503d8060008114610e86576040519150601f19603f3d011682016040523d82523d6000602084013e610e8b565b606091505b5091509150818015610eb5575080511580610eb5575080806020019051810190610eb5919061172a565b8015610ed7575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166110b79092919063ffffffff16565b9050805160001480610f63575080806020019051810190610f63919061172a565b610e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d49565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60606110c684846000856110ce565b949350505050565b606082471015611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d49565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611189919061170e565b60006040518083038185875af1925050503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b50915091506111dc878383876111e7565b979650505050505050565b6060831561127d5782516000036112765773ffffffffffffffffffffffffffffffffffffffff85163b611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d49565b50816110c6565b6110c683838151156112925781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d49919061174e565b6040516101c0810167ffffffffffffffff81118282101715611311577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133b57600080fd5b919050565b803561ffff8116811461133b57600080fd5b803565ffffffffffff8116811461133b57600080fd5b803560ff8116811461133b57600080fd5b801515811461138757600080fd5b50565b803561133b81611379565b6000604082840312156113a757600080fd5b50919050565b6000808284036101e08112156113c257600080fd5b6101c0808212156113d257600080fd5b6113da6112c6565b915084358252602085013560208301526113f660408601611317565b604083015261140760608601611317565b606083015261141860808601611340565b608083015261142960a08601611340565b60a083015261143a60c08601611317565b60c083015261144b60e08601611317565b60e083015261010061145e818701611317565b90830152610120611470868201611352565b90830152610140611482868201611368565b90830152610160611494868201611368565b908301526101806114a6868201611368565b908301526101a06114b886820161138a565b9083015290925083013567ffffffffffffffff8111156114d757600080fd5b6114e385828601611395565b9150509250929050565b6000602082840312156114ff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261153b57600080fd5b83018035915067ffffffffffffffff82111561155657600080fd5b60200191503681900382131561156b57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d0557610d05611634565b61ffff82811682821603908082111561169157611691611634565b5092915050565b8082028115828204841417610d0557610d05611634565b6000826116e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156117055781810151838201526020016116ed565b50506000910152565b600082516117208184602087016116ea565b9190910192915050565b60006020828403121561173c57600080fd5b815161174781611379565b9392505050565b602081526000825180602084015261176d8160408501602087016116ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212204f164ad9f74d85efb515fab3ce059723b15ff2d1b51c1308c6989e26aff5f0c564736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b6100366100313660046113ad565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906114ed565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff9091169161066b565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b90890189611506565b6040518563ffffffff1660e01b815260040161026a9493929190611572565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b6103cc856101800151866101a001518760600151348961014001518a61016001518b6000015160008073ffffffffffffffffffffffffffffffffffffffff168e60e0015173ffffffffffffffffffffffffffffffffffffffff1614806103c757508a5b6107df565b60008261046d576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046891906114ed565b61046f565b475b905061047b8282611663565b935061048f86602001518760a00151610cdb565b8410156104c8576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ea8660c00151876101000151886080015161ffff16896020015188610d0b565b93508215610596576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610550576040519150601f19603f3d011682016040523d82523d6000602084013e610555565b606091505b5050905080610590576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506105ca565b6105ca86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610dc49092919063ffffffff16565b85610100015173ffffffffffffffffffffffffffffffffffffffff168660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f389600001518860405161065a929190918252602082015260400190565b60405180910390a450505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106f78482610e1f565b6107d95760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526107cf9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610ee0565b6107d98482610ee0565b50505050565b8860ff1660010361090d578715610898576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b5050505050610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610861565b8860ff16600203610a4d5787156109d8576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156109ad573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109d291906114ed565b50610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df0212490889060840161098f565b8860ff16600303610bee578715610acb576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b90889060840161098f565b8015610b45576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a40161098f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015610bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d291906114ed565b8860ff16600403610c9e578715610c31576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610861565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6000612710610cea8382611676565b610cf89061ffff1685611698565b610d0291906116af565b90505b92915050565b60006107d0841115610d52576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610d64575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610d9a5760646032840204610d9d565b60005b9050808303838214610db557610db58a8a8484610fef565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e1a9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161074d565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e49919061170e565b6000604051808303816000865af19150503d8060008114610e86576040519150601f19603f3d011682016040523d82523d6000602084013e610e8b565b606091505b5091509150818015610eb5575080511580610eb5575080806020019051810190610eb5919061172a565b8015610ed7575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166110b79092919063ffffffff16565b9050805160001480610f63575080806020019051810190610f63919061172a565b610e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d49565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60606110c684846000856110ce565b949350505050565b606082471015611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d49565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611189919061170e565b60006040518083038185875af1925050503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b50915091506111dc878383876111e7565b979650505050505050565b6060831561127d5782516000036112765773ffffffffffffffffffffffffffffffffffffffff85163b611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d49565b50816110c6565b6110c683838151156112925781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d49919061174e565b6040516101c0810167ffffffffffffffff81118282101715611311577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133b57600080fd5b919050565b803561ffff8116811461133b57600080fd5b803565ffffffffffff8116811461133b57600080fd5b803560ff8116811461133b57600080fd5b801515811461138757600080fd5b50565b803561133b81611379565b6000604082840312156113a757600080fd5b50919050565b6000808284036101e08112156113c257600080fd5b6101c0808212156113d257600080fd5b6113da6112c6565b915084358252602085013560208301526113f660408601611317565b604083015261140760608601611317565b606083015261141860808601611340565b608083015261142960a08601611340565b60a083015261143a60c08601611317565b60c083015261144b60e08601611317565b60e083015261010061145e818701611317565b90830152610120611470868201611352565b90830152610140611482868201611368565b90830152610160611494868201611368565b908301526101806114a6868201611368565b908301526101a06114b886820161138a565b9083015290925083013567ffffffffffffffff8111156114d757600080fd5b6114e385828601611395565b9150509250929050565b6000602082840312156114ff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261153b57600080fd5b83018035915067ffffffffffffffff82111561155657600080fd5b60200191503681900382131561156b57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d0557610d05611634565b61ffff82811682821603908082111561169157611691611634565b5092915050565b8082028115828204841417610d0557610d05611634565b6000826116e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156117055781810151838201526020016116ed565b50506000910152565b600082516117208184602087016116ea565b9190910192915050565b60006020828403121561173c57600080fd5b815161174781611379565b9392505050565b602081526000825180602084015261176d8160408501602087016116ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212204f164ad9f74d85efb515fab3ce059723b15ff2d1b51c1308c6989e26aff5f0c564736f6c63430008130033", + "numDeployments": 8, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermitForEthToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"name\":\"curveExactInputSingle\",\"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\":\"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\":\"curveExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}],\"PermitForEthToken()\":[{\"notice\":\"A function expecting a permit was used when the input token is ETH\"}]},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\\n * Perform the swap with tokens already moved to this contract\\n */\\n function curveExactInputSingleInternal(\\n ExactInputSingleParams calldata params\\n ) internal returns (uint256 amountOut) {\\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 LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n useEth: params.tokenIn == address(0) || isToEth,\\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function curveExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (params.tokenIn == address(0)) {\\n revert PermitForEthToken();\\n }\\n\\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 return curveExactInputSingleInternal(params);\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\\n }\\n\\n return curveExactInputSingleInternal(params);\\n }\\n}\\n\",\"keccak256\":\"0x14d74eb8ac6efa00532e5de577c6b6ca66866e6991a220986ca7733d920de561\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n /**\\n * A function expecting a permit was used when the input token is ETH\\n */\\n error PermitForEthToken();\\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 curveExactInputSinglePermit(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xd034586f038b6ea01e6ce9d6497d203ef8cc5d221884f1a6f608ce08bae51904\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506119c8806100206000396000f3fe6080604052600436106100295760003560e01c806356bf88f01461002e578063aef417b114610053575b600080fd5b61004161003c366004611598565b610066565b60405190815260200160405180910390f35b6100416100613660046115f0565b610348565b60008061007a610100850160e0860161160d565b73ffffffffffffffffffffffffffffffffffffffff16036100c7576040517f53e40ce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a6100da608085016060860161160d565b84356100ed610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff169190610430565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925273ffffffffffffffffffffffffffffffffffffffff90921691632b67b57091339190819060608201908190610174906101008c01908c0161160d565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016101ab6101408b016101208c0161164a565b65ffffffffffff908116825289351660209182015290825230908201526040016101dd61014089016101208a0161164a565b65ffffffffffff1690526101f46020870187611672565b6040518563ffffffff1660e01b815260040161021394939291906116de565b600060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505061026c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333086356102a0610100890160e08a0161160d565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561031e57600080fd5b505af1158015610332573d6000803e3d6000fd5b5050505061033f836105a4565b90505b92915050565b600061035c6101408301610120840161164a565b65ffffffffffff1642111561039d576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103b0610100840160e0850161160d565b73ffffffffffffffffffffffffffffffffffffffff1614610427576103f16103de608084016060850161160d565b83356100ed610100860160e0870161160d565b61042733308435610409610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff16929190610a43565b610342826105a4565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526104bc8482610aa1565b61059e5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526105949085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610b62565b61059e8482610b62565b50505050565b600080806105ba6101208501610100860161160d565b73ffffffffffffffffffffffffffffffffffffffff16149050600081610681576105ec6101208501610100860161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c91906117a0565b610683565b475b905061073661069a6101a0860161018087016117b9565b6106ac6101c087016101a088016117ed565b6106bc608088016060890161160d565b346106cf6101608a016101408b016117b9565b6106e16101808b016101608c016117b9565b8a6000013560008073ffffffffffffffffffffffffffffffffffffffff168d60e0016020810190610712919061160d565b73ffffffffffffffffffffffffffffffffffffffff16148061073157508a5b610c7b565b6000826107e45761074f6101208601610100870161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df91906117a0565b6107e6565b475b90506107f28282611839565b9350610811602086013561080c60c0880160a0890161184c565b611177565b84101561084a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088e61085d60e0870160c0880161160d565b61086f6101208801610100890161160d565b61087f60a0890160808a0161184c565b61ffff1688602001358861119e565b935082156109455760006108a8606087016040880161160d565b73ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146108ff576040519150601f19603f3d011682016040523d82523d6000602084013e610904565b606091505b505090508061093f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610988565b610988610958606087016040880161160d565b8561096b61012089016101008a0161160d565b73ffffffffffffffffffffffffffffffffffffffff169190611252565b61099a6101208601610100870161160d565b73ffffffffffffffffffffffffffffffffffffffff166109c1610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff166109e760e0880160c0890161160d565b60408051893581526020810189905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261059e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610512565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610acb9190611894565b6000604051808303816000865af19150503d8060008114610b08576040519150601f19603f3d011682016040523d82523d6000602084013e610b0d565b606091505b5091509150818015610b37575080511580610b37575080806020019051810190610b3791906118b0565b8015610b59575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610bc4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112a89092919063ffffffff16565b9050805160001480610be5575080806020019051810190610be591906118b0565b610c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b8860ff16600103610da9578715610d34576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015610d1657600080fd5b505af1158015610d2a573d6000803e3d6000fd5b505050505061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610cfd565b8860ff16600203610ee9578715610e74576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015610e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b5061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610e2b565b8860ff1660030361108a578715610f67576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401610e2b565b8015610fe1576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401610e2b565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015611066573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b8860ff1660040361113a5787156110cd576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610cfd565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600061271061118683826118cd565b6111949061ffff16856118ef565b61033f9190611906565b60006107d08411156111e0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d06004820152602401610c6d565b600082848111156111f2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611228576064603284020461122b565b60005b9050808303838214611243576112438a8a84846112bf565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c769084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610512565b60606112b78484600085611387565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606082471015611419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c6d565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516114429190611894565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b5091509150611495878383876114a0565b979650505050505050565b6060831561153657825160000361152f5773ffffffffffffffffffffffffffffffffffffffff85163b61152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c6d565b50816112b7565b6112b7838381511561154b5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9190611941565b60006101c0828403121561159257600080fd5b50919050565b6000806101e083850312156115ac57600080fd5b6115b6848461157f565b91506101c083013567ffffffffffffffff8111156115d357600080fd5b8301604081860312156115e557600080fd5b809150509250929050565b60006101c0828403121561160357600080fd5b61033f838361157f565b60006020828403121561161f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461164357600080fd5b9392505050565b60006020828403121561165c57600080fd5b813565ffffffffffff8116811461164357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126116a757600080fd5b83018035915067ffffffffffffffff8211156116c257600080fd5b6020019150368190038213156116d757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156117b257600080fd5b5051919050565b6000602082840312156117cb57600080fd5b813560ff8116811461164357600080fd5b80151581146117ea57600080fd5b50565b6000602082840312156117ff57600080fd5b8135611643816117dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156103425761034261180a565b60006020828403121561185e57600080fd5b813561ffff8116811461164357600080fd5b60005b8381101561188b578181015183820152602001611873565b50506000910152565b600082516118a6818460208701611870565b9190910192915050565b6000602082840312156118c257600080fd5b8151611643816117dc565b61ffff8281168282160390808211156118e8576118e861180a565b5092915050565b80820281158282048414176103425761034261180a565b60008261193c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6020815260008251806020840152611960816040850160208701611870565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202b55d2f11aa7f1395a3e9c79ad5594ecdb6d8158214c767aed2d3da3a5500d1264736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c806356bf88f01461002e578063aef417b114610053575b600080fd5b61004161003c366004611598565b610066565b60405190815260200160405180910390f35b6100416100613660046115f0565b610348565b60008061007a610100850160e0860161160d565b73ffffffffffffffffffffffffffffffffffffffff16036100c7576040517f53e40ce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a6100da608085016060860161160d565b84356100ed610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff169190610430565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925273ffffffffffffffffffffffffffffffffffffffff90921691632b67b57091339190819060608201908190610174906101008c01908c0161160d565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016101ab6101408b016101208c0161164a565b65ffffffffffff908116825289351660209182015290825230908201526040016101dd61014089016101208a0161164a565b65ffffffffffff1690526101f46020870187611672565b6040518563ffffffff1660e01b815260040161021394939291906116de565b600060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505061026c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333086356102a0610100890160e08a0161160d565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561031e57600080fd5b505af1158015610332573d6000803e3d6000fd5b5050505061033f836105a4565b90505b92915050565b600061035c6101408301610120840161164a565b65ffffffffffff1642111561039d576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103b0610100840160e0850161160d565b73ffffffffffffffffffffffffffffffffffffffff1614610427576103f16103de608084016060850161160d565b83356100ed610100860160e0870161160d565b61042733308435610409610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff16929190610a43565b610342826105a4565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526104bc8482610aa1565b61059e5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526105949085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610b62565b61059e8482610b62565b50505050565b600080806105ba6101208501610100860161160d565b73ffffffffffffffffffffffffffffffffffffffff16149050600081610681576105ec6101208501610100860161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c91906117a0565b610683565b475b905061073661069a6101a0860161018087016117b9565b6106ac6101c087016101a088016117ed565b6106bc608088016060890161160d565b346106cf6101608a016101408b016117b9565b6106e16101808b016101608c016117b9565b8a6000013560008073ffffffffffffffffffffffffffffffffffffffff168d60e0016020810190610712919061160d565b73ffffffffffffffffffffffffffffffffffffffff16148061073157508a5b610c7b565b6000826107e45761074f6101208601610100870161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df91906117a0565b6107e6565b475b90506107f28282611839565b9350610811602086013561080c60c0880160a0890161184c565b611177565b84101561084a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088e61085d60e0870160c0880161160d565b61086f6101208801610100890161160d565b61087f60a0890160808a0161184c565b61ffff1688602001358861119e565b935082156109455760006108a8606087016040880161160d565b73ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146108ff576040519150601f19603f3d011682016040523d82523d6000602084013e610904565b606091505b505090508061093f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610988565b610988610958606087016040880161160d565b8561096b61012089016101008a0161160d565b73ffffffffffffffffffffffffffffffffffffffff169190611252565b61099a6101208601610100870161160d565b73ffffffffffffffffffffffffffffffffffffffff166109c1610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff166109e760e0880160c0890161160d565b60408051893581526020810189905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261059e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610512565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610acb9190611894565b6000604051808303816000865af19150503d8060008114610b08576040519150601f19603f3d011682016040523d82523d6000602084013e610b0d565b606091505b5091509150818015610b37575080511580610b37575080806020019051810190610b3791906118b0565b8015610b59575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610bc4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112a89092919063ffffffff16565b9050805160001480610be5575080806020019051810190610be591906118b0565b610c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b8860ff16600103610da9578715610d34576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015610d1657600080fd5b505af1158015610d2a573d6000803e3d6000fd5b505050505061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610cfd565b8860ff16600203610ee9578715610e74576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015610e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b5061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610e2b565b8860ff1660030361108a578715610f67576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401610e2b565b8015610fe1576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401610e2b565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015611066573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b8860ff1660040361113a5787156110cd576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610cfd565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600061271061118683826118cd565b6111949061ffff16856118ef565b61033f9190611906565b60006107d08411156111e0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d06004820152602401610c6d565b600082848111156111f2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611228576064603284020461122b565b60005b9050808303838214611243576112438a8a84846112bf565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c769084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610512565b60606112b78484600085611387565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606082471015611419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c6d565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516114429190611894565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b5091509150611495878383876114a0565b979650505050505050565b6060831561153657825160000361152f5773ffffffffffffffffffffffffffffffffffffffff85163b61152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c6d565b50816112b7565b6112b7838381511561154b5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9190611941565b60006101c0828403121561159257600080fd5b50919050565b6000806101e083850312156115ac57600080fd5b6115b6848461157f565b91506101c083013567ffffffffffffffff8111156115d357600080fd5b8301604081860312156115e557600080fd5b809150509250929050565b60006101c0828403121561160357600080fd5b61033f838361157f565b60006020828403121561161f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461164357600080fd5b9392505050565b60006020828403121561165c57600080fd5b813565ffffffffffff8116811461164357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126116a757600080fd5b83018035915067ffffffffffffffff8211156116c257600080fd5b6020019150368190038213156116d757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156117b257600080fd5b5051919050565b6000602082840312156117cb57600080fd5b813560ff8116811461164357600080fd5b80151581146117ea57600080fd5b50565b6000602082840312156117ff57600080fd5b8135611643816117dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156103425761034261180a565b60006020828403121561185e57600080fd5b813561ffff8116811461164357600080fd5b60005b8381101561188b578181015183820152602001611873565b50506000910152565b600082516118a6818460208701611870565b9190910192915050565b6000602082840312156118c257600080fd5b8151611643816117dc565b61ffff8281168282160390808211156118e8576118e861180a565b5092915050565b80820281158282048414176103425761034261180a565b60008261193c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6020815260008251806020840152611960816040850160208701611870565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202b55d2f11aa7f1395a3e9c79ad5594ecdb6d8158214c767aed2d3da3a5500d1264736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, @@ -261,6 +357,11 @@ { "notice": "The swap fee is over the maximum allowed" } + ], + "PermitForEthToken()": [ + { + "notice": "A function expecting a permit was used when the input token is ETH" + } ] }, "kind": "user", diff --git a/packages/hardhat/deployments/base/Stargate.json b/packages/hardhat/deployments/base/Stargate.json index 18c41562..ba18c539 100644 --- a/packages/hardhat/deployments/base/Stargate.json +++ b/packages/hardhat/deployments/base/Stargate.json @@ -1,5 +1,5 @@ { - "address": "0xBc3DF9Aa6223128F517fDb3C93d51B1a28F0f96A", + "address": "0x352AfE52B0972d67148C01690cB90281fBF6bC35", "abi": [ { "inputs": [ @@ -124,6 +124,76 @@ "stateMutability": "payable", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint160", + "name": "amountIn", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "amountOutExpected", + "type": "uint160" + }, + { + "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": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "srcPoolId", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "dstPoolId", + "type": "uint8" + } + ], + "internalType": "struct IStargate.JumpTokenParams", + "name": "params", + "type": "tuple" + } + ], + "name": "stargateJumpToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -206,34 +276,34 @@ "type": "tuple" } ], - "name": "stargateJumpToken", + "name": "stargateJumpTokenPermit", "outputs": [], "stateMutability": "payable", "type": "function" } ], - "transactionHash": "0x636f1acfb3746526a3e9e54857aa3c594277eacba8371c9ee2dfe512cc4fe6e4", + "transactionHash": "0x0277e0e98a4ec699382f58da90358b3f27c5d6ce60d31b19e239da9c2524fc8a", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xBc3DF9Aa6223128F517fDb3C93d51B1a28F0f96A", - "transactionIndex": 13, - "gasUsed": "1184682", + "contractAddress": "0x352AfE52B0972d67148C01690cB90281fBF6bC35", + "transactionIndex": 9, + "gasUsed": "1254228", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc8226367857f752df5b53bc7e01a75bb94fef207b88c080f5585ce429f498ff3", - "transactionHash": "0x636f1acfb3746526a3e9e54857aa3c594277eacba8371c9ee2dfe512cc4fe6e4", + "blockHash": "0xe16c9a71349e29baae5ec231ba6fd5cfa8765ad399b1f764bfc50812a7790845", + "transactionHash": "0x0277e0e98a4ec699382f58da90358b3f27c5d6ce60d31b19e239da9c2524fc8a", "logs": [], - "blockNumber": 5459976, - "cumulativeGasUsed": "5643939", + "blockNumber": 6230707, + "cumulativeGasUsed": "23182048", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpNativeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"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\":\"stargateJumpToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Stargate.sol\":\"Stargate\"},\"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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract Stargate is IStargate {\\n using SafeERC20 for IERC20;\\n\\n function stargateJumpToken(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.token,\\n amount: 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 // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n uint160(params.amountIn),\\n params.token\\n );\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.token,\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n // NOTE: This lookup is spending 319 gas\\n IStargateRouter stargateRouter = IStargateRouter(\\n LibWarp.state().stargateComposer.stargateRouter()\\n );\\n\\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\\n\\n unchecked {\\n stargateRouter.swap{value: msg.value}({\\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\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n address(0),\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n unchecked {\\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n}\\n\",\"keccak256\":\"0x384ff4fd006f55fd52c6532724722c9d8709db7760e8296c8a9447a19bd148f1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/IStargate.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\n\\ninterface IStargate is ILibStarVault {\\n error InsufficientEthValue();\\n\\n struct JumpTokenParams {\\n address token;\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n struct JumpNativeParams {\\n /**\\n * The amount in is passed to distinguish the amount to bridge from the fee\\n */\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n function stargateJumpToken(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\\n}\\n\",\"keccak256\":\"0x4464ecac16a3c449c8f7983ac21ba54a44ac02194baa590c480b6ffc1cddd478\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b5061148c806100206000396000f3fe6080604052600436106100295760003560e01c806329859a061461002e578063c2bee2af14610043575b600080fd5b61004161003c366004610fca565b610056565b005b610041610051366004611029565b610618565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100b760208a018a611067565b73ffffffffffffffffffffffffffffffffffffffff1681526020018860200160208101906100e59190611067565b73ffffffffffffffffffffffffffffffffffffffff16815260200161011060e08a0160c08b0161108b565b65ffffffffffff9081168252883516602091820152908252309082015260400161014060e0880160c0890161108b565b65ffffffffffff16905261015760208601866110b3565b6040518563ffffffff1660e01b8152600401610176949392919061111f565b600060405180830381600087803b15801561019057600080fd5b505af11580156101a4573d6000803e3d6000fd5b505050506101cf7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633306102006040870160208801611067565b61020d6020880188611067565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561028b57600080fd5b505af115801561029f573d6000803e3d6000fd5b50505050600061032d8360e00160208101906102bb9190611067565b6102c86020860186611067565b6102d860c0870160a088016111e1565b61ffff166102ec6040880160208901611067565b73ffffffffffffffffffffffffffffffffffffffff166103126040890160208a01611067565b73ffffffffffffffffffffffffffffffffffffffff16610905565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190611205565b905061041581836103f86020880188611067565b73ffffffffffffffffffffffffffffffffffffffff1691906109be565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc34610444610120880161010089016111e1565b61045661014089016101208a01611222565b6104686101608a016101408b01611222565b33888061047b60408e0160208f01611067565b73ffffffffffffffffffffffffffffffffffffffff16036104a260608e0160408f01611067565b73ffffffffffffffffffffffffffffffffffffffff16116104c4576000610534565b6105348a8d60200160208101906104db9190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d60400160208101906105059190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d608001602081019061052f91906111e1565b610aee565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508d60600160208101906105739190611067565b6040516020016105ae919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016105e09897969594939291906112b3565b6000604051808303818588803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050505050505050565b6106256020820182611067565b73ffffffffffffffffffffffffffffffffffffffff16341015610674576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106cf61068960e0840160c08501611067565b600061069b60a08601608087016111e1565b61ffff166106ac6020870187611067565b73ffffffffffffffffffffffffffffffffffffffff166103126020880188611067565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261071d6020860186611067565b73ffffffffffffffffffffffffffffffffffffffff16033403610747610100860160e087016111e1565b61075961012087016101008801611222565b61076b61014088016101208901611222565b33878061077b60208c018c611067565b73ffffffffffffffffffffffffffffffffffffffff16036107a260408c0160208d01611067565b73ffffffffffffffffffffffffffffffffffffffff16116107c4576000610823565b610823896107d560208d018d611067565b73ffffffffffffffffffffffffffffffffffffffff16036107fc60408d0160208e01611067565b73ffffffffffffffffffffffffffffffffffffffff160361052f60808d0160608e016111e1565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b60400160208101906108629190611067565b60405160200161089d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016108cf9897969594939291906112b3565b6000604051808303818588803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b50505050505050565b60006107d084111561094c576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561095e575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109945760646032840204610997565b60005b90508083038382146109af576109af8a8a8484610b1e565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610a4a8482610be6565b610ae8576040805173ffffffffffffffffffffffffffffffffffffffff8516602482015260006044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610ade908590610ca7565b610ae88482610ca7565b50505050565b6000612710610afd8382611391565b610b0b9061ffff16856113b3565b610b1591906113ca565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c109190611405565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611421565b8015610c9e575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610dbb9092919063ffffffff16565b9050805160001480610d2a575080806020019051810190610d2a9190611421565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610943565b505050565b6060610dca8484600085610dd2565b949350505050565b606082471015610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610943565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610e8d9190611405565b60006040518083038185875af1925050503d8060008114610eca576040519150601f19603f3d011682016040523d82523d6000602084013e610ecf565b606091505b5091509150610ee087838387610eeb565b979650505050505050565b60608315610f81578251600003610f7a5773ffffffffffffffffffffffffffffffffffffffff85163b610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b5081610dca565b610dca8383815115610f965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109439190611443565b600080828403610180811215610fdf57600080fd5b61016080821215610fef57600080fd5b849350830135905067ffffffffffffffff81111561100c57600080fd5b83016040818603121561101e57600080fd5b809150509250929050565b6000610140828403121561103c57600080fd5b50919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461106457600080fd5b50565b60006020828403121561107957600080fd5b813561108481611042565b9392505050565b60006020828403121561109d57600080fd5b813565ffffffffffff8116811461108457600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110e857600080fd5b83018035915067ffffffffffffffff82111561110357600080fd5b60200191503681900382131561111857600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156111f357600080fd5b813561ffff8116811461108457600080fd5b60006020828403121561121757600080fd5b815161108481611042565b60006020828403121561123457600080fd5b813560ff8116811461108457600080fd5b60005b83811015611260578181015183820152602001611248565b50506000910152565b60008151808452611281816020860160208601611245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c08401528451818401525060208401516101408301526040840151606061016084015261132c610180840182611269565b905082810360e08401526113408185611269565b838103610100850152600081529050602081019b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156113ac576113ac611362565b5092915050565b8082028115828204841417610b1857610b18611362565b600082611400577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251611417818460208701611245565b9190910192915050565b60006020828403121561143357600080fd5b8151801515811461108457600080fd5b602081526000610b15602083018461126956fea2646970667358221220fd4949e43a56ae6a92fdbb921568c2bc2a7013da24304d0b873ce9c5e7515c0264736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806329859a061461002e578063c2bee2af14610043575b600080fd5b61004161003c366004610fca565b610056565b005b610041610051366004611029565b610618565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100b760208a018a611067565b73ffffffffffffffffffffffffffffffffffffffff1681526020018860200160208101906100e59190611067565b73ffffffffffffffffffffffffffffffffffffffff16815260200161011060e08a0160c08b0161108b565b65ffffffffffff9081168252883516602091820152908252309082015260400161014060e0880160c0890161108b565b65ffffffffffff16905261015760208601866110b3565b6040518563ffffffff1660e01b8152600401610176949392919061111f565b600060405180830381600087803b15801561019057600080fd5b505af11580156101a4573d6000803e3d6000fd5b505050506101cf7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633306102006040870160208801611067565b61020d6020880188611067565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561028b57600080fd5b505af115801561029f573d6000803e3d6000fd5b50505050600061032d8360e00160208101906102bb9190611067565b6102c86020860186611067565b6102d860c0870160a088016111e1565b61ffff166102ec6040880160208901611067565b73ffffffffffffffffffffffffffffffffffffffff166103126040890160208a01611067565b73ffffffffffffffffffffffffffffffffffffffff16610905565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190611205565b905061041581836103f86020880188611067565b73ffffffffffffffffffffffffffffffffffffffff1691906109be565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc34610444610120880161010089016111e1565b61045661014089016101208a01611222565b6104686101608a016101408b01611222565b33888061047b60408e0160208f01611067565b73ffffffffffffffffffffffffffffffffffffffff16036104a260608e0160408f01611067565b73ffffffffffffffffffffffffffffffffffffffff16116104c4576000610534565b6105348a8d60200160208101906104db9190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d60400160208101906105059190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d608001602081019061052f91906111e1565b610aee565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508d60600160208101906105739190611067565b6040516020016105ae919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016105e09897969594939291906112b3565b6000604051808303818588803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050505050505050565b6106256020820182611067565b73ffffffffffffffffffffffffffffffffffffffff16341015610674576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106cf61068960e0840160c08501611067565b600061069b60a08601608087016111e1565b61ffff166106ac6020870187611067565b73ffffffffffffffffffffffffffffffffffffffff166103126020880188611067565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261071d6020860186611067565b73ffffffffffffffffffffffffffffffffffffffff16033403610747610100860160e087016111e1565b61075961012087016101008801611222565b61076b61014088016101208901611222565b33878061077b60208c018c611067565b73ffffffffffffffffffffffffffffffffffffffff16036107a260408c0160208d01611067565b73ffffffffffffffffffffffffffffffffffffffff16116107c4576000610823565b610823896107d560208d018d611067565b73ffffffffffffffffffffffffffffffffffffffff16036107fc60408d0160208e01611067565b73ffffffffffffffffffffffffffffffffffffffff160361052f60808d0160608e016111e1565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b60400160208101906108629190611067565b60405160200161089d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016108cf9897969594939291906112b3565b6000604051808303818588803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b50505050505050565b60006107d084111561094c576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561095e575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109945760646032840204610997565b60005b90508083038382146109af576109af8a8a8484610b1e565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610a4a8482610be6565b610ae8576040805173ffffffffffffffffffffffffffffffffffffffff8516602482015260006044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610ade908590610ca7565b610ae88482610ca7565b50505050565b6000612710610afd8382611391565b610b0b9061ffff16856113b3565b610b1591906113ca565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c109190611405565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611421565b8015610c9e575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610dbb9092919063ffffffff16565b9050805160001480610d2a575080806020019051810190610d2a9190611421565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610943565b505050565b6060610dca8484600085610dd2565b949350505050565b606082471015610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610943565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610e8d9190611405565b60006040518083038185875af1925050503d8060008114610eca576040519150601f19603f3d011682016040523d82523d6000602084013e610ecf565b606091505b5091509150610ee087838387610eeb565b979650505050505050565b60608315610f81578251600003610f7a5773ffffffffffffffffffffffffffffffffffffffff85163b610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b5081610dca565b610dca8383815115610f965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109439190611443565b600080828403610180811215610fdf57600080fd5b61016080821215610fef57600080fd5b849350830135905067ffffffffffffffff81111561100c57600080fd5b83016040818603121561101e57600080fd5b809150509250929050565b6000610140828403121561103c57600080fd5b50919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461106457600080fd5b50565b60006020828403121561107957600080fd5b813561108481611042565b9392505050565b60006020828403121561109d57600080fd5b813565ffffffffffff8116811461108457600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110e857600080fd5b83018035915067ffffffffffffffff82111561110357600080fd5b60200191503681900382131561111857600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156111f357600080fd5b813561ffff8116811461108457600080fd5b60006020828403121561121757600080fd5b815161108481611042565b60006020828403121561123457600080fd5b813560ff8116811461108457600080fd5b60005b83811015611260578181015183820152602001611248565b50506000910152565b60008151808452611281816020860160208601611245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c08401528451818401525060208401516101408301526040840151606061016084015261132c610180840182611269565b905082810360e08401526113408185611269565b838103610100850152600081529050602081019b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156113ac576113ac611362565b5092915050565b8082028115828204841417610b1857610b18611362565b600082611400577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251611417818460208701611245565b9190910192915050565b60006020828403121561143357600080fd5b8151801515811461108457600080fd5b602081526000610b15602083018461126956fea2646970667358221220fd4949e43a56ae6a92fdbb921568c2bc2a7013da24304d0b873ce9c5e7515c0264736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpNativeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"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\":\"stargateJumpTokenPermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Stargate.sol\":\"Stargate\"},\"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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract Stargate is IStargate {\\n using SafeERC20 for IERC20;\\n\\n /**\\n * Jump tokens with Stargate with input tokens already moved to this contract\\n */\\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.token,\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n // NOTE: This lookup is spending 319 gas\\n IStargateRouter stargateRouter = IStargateRouter(\\n LibWarp.state().stargateComposer.stargateRouter()\\n );\\n\\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\\n\\n unchecked {\\n stargateRouter.swap{value: msg.value}({\\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\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n\\n function stargateJumpTokenPermit(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.token,\\n amount: 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 // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n uint160(params.amountIn),\\n params.token\\n );\\n\\n stargateJumpTokenInternal(params);\\n }\\n\\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\\n // Transfer tokens from the sender to this contract\\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\\n\\n stargateJumpTokenInternal(params);\\n }\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n address(0),\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n unchecked {\\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6abe4954877eed5b5a9c473441ac11e6f505d6cedc5c1d9489960227c5fb6f84\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/IStargate.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\n\\ninterface IStargate is ILibStarVault {\\n error InsufficientEthValue();\\n\\n struct JumpTokenParams {\\n address token;\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n struct JumpNativeParams {\\n /**\\n * The amount in is passed to distinguish the amount to bridge from the fee\\n */\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\\n\\n function stargateJumpTokenPermit(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\\n}\\n\",\"keccak256\":\"0xb35bd721e5ab9f7cd120a61bdafd807dcebd1cf71f5189662697f47a1f10986c\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506115d1806100206000396000f3fe6080604052600436106100345760003560e01c80638be9f27914610039578063ba2466d41461004e578063c2bee2af14610061575b600080fd5b61004c610047366004611102565b610074565b005b61004c61005c36600461115a565b6102ce565b61004c61006f366004611177565b610330565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100d560208a018a6111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200188602001602081019061010391906111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200161012e60e08a0160c08b016111d0565b65ffffffffffff9081168252883516602091820152908252309082015260400161015e60e0880160c089016111d0565b65ffffffffffff16905261017560208601866111f8565b6040518563ffffffff1660e01b81526004016101949493929190611264565b600060405180830381600087803b1580156101ae57600080fd5b505af11580156101c2573d6000803e3d6000fd5b505050506101ed7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333061021e60408701602088016111ac565b61022b60208801886111ac565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102a957600080fd5b505af11580156102bd573d6000803e3d6000fd5b505050506102ca8261063d565b5050565b61032433306102e360408501602086016111ac565b73ffffffffffffffffffffffffffffffffffffffff1661030660208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff16929190610986565b61032d8161063d565b50565b61033d60208201826111ac565b73ffffffffffffffffffffffffffffffffffffffff1634101561038c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104026103a160e0840160c085016111ac565b60006103b360a0860160808701611326565b61ffff166103c460208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760208801886111ac565b73ffffffffffffffffffffffffffffffffffffffff16610a68565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261045060208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff1603340361047a610100860160e08701611326565b61048c6101208701610100880161134a565b61049e6101408801610120890161134a565b3387806104ae60208c018c6111ac565b73ffffffffffffffffffffffffffffffffffffffff16036104d560408c0160208d016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116104f757600061055b565b61055b8961050860208d018d6111ac565b73ffffffffffffffffffffffffffffffffffffffff160361052f60408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660808d0160608e01611326565b610b21565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b604001602081019061059a91906111ac565b6040516020016105d5919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016106079897969594939291906113db565b6000604051808303818588803b15801561062057600080fd5b505af1158015610634573d6000803e3d6000fd5b50505050505050565b60006106aa610653610100840160e085016111ac565b61066060208501856111ac565b61067060c0860160a08701611326565b61ffff1661068460408701602088016111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760408801602089016111ac565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610761919061148a565b9050610792818361077560208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff169190610b51565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc346107c161012087016101008801611326565b6107d36101408801610120890161134a565b6107e561016089016101408a0161134a565b3388806107f860408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361081f60608d0160408e016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116108415760006108a3565b6108a38a61085560408e0160208f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361087c60608e0160408f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660a08e0160808f01611326565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60600160208101906108e291906111ac565b60405160200161091d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b815260040161094f9897969594939291906113db565b6000604051808303818588803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a629085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610c3d565b50505050565b60006107d0841115610aaf576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610ac1575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610af75760646032840204610afa565b60005b9050808303838214610b1257610b128a8a8484610d51565b50505090910395945050505050565b6000612710610b3083826114d6565b610b3e9061ffff16856114f8565b610b48919061150f565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610bdd8482610e19565b610a625760405173ffffffffffffffffffffffffffffffffffffffff8416602482015260006044820152610c379085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109e0565b610a6284825b6000610c9f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610eda9092919063ffffffff16565b9050805160001480610cc0575080806020019051810190610cc0919061154a565b610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa6565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e43919061156c565b6000604051808303816000865af19150503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5091509150818015610eaf575080511580610eaf575080806020019051810190610eaf919061154a565b8015610ed1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060610ee98484600085610ef1565b949350505050565b606082471015610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fac919061156c565b60006040518083038185875af1925050503d8060008114610fe9576040519150601f19603f3d011682016040523d82523d6000602084013e610fee565b606091505b5091509150610fff8783838761100a565b979650505050505050565b606083156110a05782516000036110995773ffffffffffffffffffffffffffffffffffffffff85163b611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa6565b5081610ee9565b610ee983838151156110b55781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa69190611588565b600061016082840312156110fc57600080fd5b50919050565b600080610180838503121561111657600080fd5b61112084846110e9565b915061016083013567ffffffffffffffff81111561113d57600080fd5b83016040818603121561114f57600080fd5b809150509250929050565b6000610160828403121561116d57600080fd5b610b4883836110e9565b600061014082840312156110fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461032d57600080fd5b6000602082840312156111be57600080fd5b81356111c98161118a565b9392505050565b6000602082840312156111e257600080fd5b813565ffffffffffff811681146111c957600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261122d57600080fd5b83018035915067ffffffffffffffff82111561124857600080fd5b60200191503681900382131561125d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60006020828403121561133857600080fd5b813561ffff811681146111c957600080fd5b60006020828403121561135c57600080fd5b813560ff811681146111c957600080fd5b60005b83811015611388578181015183820152602001611370565b50506000910152565b600081518084526113a981602086016020860161136d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c084015284518184015250602084015161014083015260408401516060610160840152611454610180840182611391565b905082810360e08401526114688185611391565b838103610100850152600081529050602081019b9a5050505050505050505050565b60006020828403121561149c57600080fd5b81516111c98161118a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156114f1576114f16114a7565b5092915050565b8082028115828204841417610b4b57610b4b6114a7565b600082611545577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561155c57600080fd5b815180151581146111c957600080fd5b6000825161157e81846020870161136d565b9190910192915050565b602081526000610b48602083018461139156fea26469706673582212208328d8149ca8eb632152123f06714fc50d6667b0823eba29b328ace315d4e37464736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c80638be9f27914610039578063ba2466d41461004e578063c2bee2af14610061575b600080fd5b61004c610047366004611102565b610074565b005b61004c61005c36600461115a565b6102ce565b61004c61006f366004611177565b610330565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100d560208a018a6111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200188602001602081019061010391906111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200161012e60e08a0160c08b016111d0565b65ffffffffffff9081168252883516602091820152908252309082015260400161015e60e0880160c089016111d0565b65ffffffffffff16905261017560208601866111f8565b6040518563ffffffff1660e01b81526004016101949493929190611264565b600060405180830381600087803b1580156101ae57600080fd5b505af11580156101c2573d6000803e3d6000fd5b505050506101ed7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333061021e60408701602088016111ac565b61022b60208801886111ac565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102a957600080fd5b505af11580156102bd573d6000803e3d6000fd5b505050506102ca8261063d565b5050565b61032433306102e360408501602086016111ac565b73ffffffffffffffffffffffffffffffffffffffff1661030660208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff16929190610986565b61032d8161063d565b50565b61033d60208201826111ac565b73ffffffffffffffffffffffffffffffffffffffff1634101561038c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104026103a160e0840160c085016111ac565b60006103b360a0860160808701611326565b61ffff166103c460208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760208801886111ac565b73ffffffffffffffffffffffffffffffffffffffff16610a68565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261045060208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff1603340361047a610100860160e08701611326565b61048c6101208701610100880161134a565b61049e6101408801610120890161134a565b3387806104ae60208c018c6111ac565b73ffffffffffffffffffffffffffffffffffffffff16036104d560408c0160208d016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116104f757600061055b565b61055b8961050860208d018d6111ac565b73ffffffffffffffffffffffffffffffffffffffff160361052f60408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660808d0160608e01611326565b610b21565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b604001602081019061059a91906111ac565b6040516020016105d5919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016106079897969594939291906113db565b6000604051808303818588803b15801561062057600080fd5b505af1158015610634573d6000803e3d6000fd5b50505050505050565b60006106aa610653610100840160e085016111ac565b61066060208501856111ac565b61067060c0860160a08701611326565b61ffff1661068460408701602088016111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760408801602089016111ac565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610761919061148a565b9050610792818361077560208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff169190610b51565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc346107c161012087016101008801611326565b6107d36101408801610120890161134a565b6107e561016089016101408a0161134a565b3388806107f860408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361081f60608d0160408e016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116108415760006108a3565b6108a38a61085560408e0160208f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361087c60608e0160408f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660a08e0160808f01611326565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60600160208101906108e291906111ac565b60405160200161091d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b815260040161094f9897969594939291906113db565b6000604051808303818588803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a629085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610c3d565b50505050565b60006107d0841115610aaf576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610ac1575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610af75760646032840204610afa565b60005b9050808303838214610b1257610b128a8a8484610d51565b50505090910395945050505050565b6000612710610b3083826114d6565b610b3e9061ffff16856114f8565b610b48919061150f565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610bdd8482610e19565b610a625760405173ffffffffffffffffffffffffffffffffffffffff8416602482015260006044820152610c379085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109e0565b610a6284825b6000610c9f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610eda9092919063ffffffff16565b9050805160001480610cc0575080806020019051810190610cc0919061154a565b610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa6565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e43919061156c565b6000604051808303816000865af19150503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5091509150818015610eaf575080511580610eaf575080806020019051810190610eaf919061154a565b8015610ed1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060610ee98484600085610ef1565b949350505050565b606082471015610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fac919061156c565b60006040518083038185875af1925050503d8060008114610fe9576040519150601f19603f3d011682016040523d82523d6000602084013e610fee565b606091505b5091509150610fff8783838761100a565b979650505050505050565b606083156110a05782516000036110995773ffffffffffffffffffffffffffffffffffffffff85163b611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa6565b5081610ee9565b610ee983838151156110b55781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa69190611588565b600061016082840312156110fc57600080fd5b50919050565b600080610180838503121561111657600080fd5b61112084846110e9565b915061016083013567ffffffffffffffff81111561113d57600080fd5b83016040818603121561114f57600080fd5b809150509250929050565b6000610160828403121561116d57600080fd5b610b4883836110e9565b600061014082840312156110fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461032d57600080fd5b6000602082840312156111be57600080fd5b81356111c98161118a565b9392505050565b6000602082840312156111e257600080fd5b813565ffffffffffff811681146111c957600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261122d57600080fd5b83018035915067ffffffffffffffff82111561124857600080fd5b60200191503681900382131561125d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60006020828403121561133857600080fd5b813561ffff811681146111c957600080fd5b60006020828403121561135c57600080fd5b813560ff811681146111c957600080fd5b60005b83811015611388578181015183820152602001611370565b50506000910152565b600081518084526113a981602086016020860161136d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c084015284518184015250602084015161014083015260408401516060610160840152611454610180840182611391565b905082810360e08401526114688185611391565b838103610100850152600081529050602081019b9a5050505050505050505050565b60006020828403121561149c57600080fd5b81516111c98161118a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156114f1576114f16114a7565b5092915050565b8082028115828204841417610b4b57610b4b6114a7565b600082611545577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561155c57600080fd5b815180151581146111c957600080fd5b6000825161157e81846020870161136d565b9190910192915050565b602081526000610b48602083018461139156fea26469706673582212208328d8149ca8eb632152123f06714fc50d6667b0823eba29b328ace315d4e37464736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/base/UniV2LikeFacet.json b/packages/hardhat/deployments/base/UniV2LikeFacet.json index 06b41e58..2545aa1b 100644 --- a/packages/hardhat/deployments/base/UniV2LikeFacet.json +++ b/packages/hardhat/deployments/base/UniV2LikeFacet.json @@ -1,5 +1,5 @@ { - "address": "0xd7f9d9b2245a09457BfbCAE5F39292596C1879E9", + "address": "0xb8B3A2C8D3062cae23AbB5A0B29D6DEE88167E70", "abi": [ { "inputs": [], @@ -116,6 +116,77 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV2LikeExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -193,7 +264,83 @@ "type": "tuple" } ], - "name": "uniswapV2LikeExactInput", + "name": "uniswapV2LikeExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV2LikeExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -286,7 +433,7 @@ "type": "tuple" } ], - "name": "uniswapV2LikeExactInputSingle", + "name": "uniswapV2LikeExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -294,32 +441,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0x9aa21ab4b08f86d0fe83464459b73496902eb0704b0e9a0175bf6444fd8d7ebc", + "transactionHash": "0xef678311c50d6ef1137f324258ae1e63da55a0e7f5f88eabbda3c7774b102020", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xd7f9d9b2245a09457BfbCAE5F39292596C1879E9", - "transactionIndex": 7, - "gasUsed": "2101579", + "contractAddress": "0xb8B3A2C8D3062cae23AbB5A0B29D6DEE88167E70", + "transactionIndex": 1, + "gasUsed": "2340469", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x39858fd38eeaba9ece77143137438eb3ccd00fccafdc394cf4dcdeda6a7dbc6a", - "transactionHash": "0x9aa21ab4b08f86d0fe83464459b73496902eb0704b0e9a0175bf6444fd8d7ebc", + "blockHash": "0x3ed0be8d0bffe922c9f212d4370df2099b9cebbd4f781fde868dc671c1497a5a", + "transactionHash": "0xef678311c50d6ef1137f324258ae1e63da55a0e7f5f88eabbda3c7774b102020", "logs": [], - "blockNumber": 5459495, - "cumulativeGasUsed": "2454555", + "blockNumber": 6230651, + "cumulativeGasUsed": "2390970", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 5, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokens[0],\\n isToEth ? address(0) : params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x4d807156203d016fd7fe1ff2dd503972c0f07d9d8f1b0794aca4459c1ea03b7a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Like is ILibStarVault, ILibWarp {\\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\":\"0x80c9be72cf89c5673f0acfb44d672ae65e86062906042a31007a9737c9e1a3db\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612542806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611e34565b610066565b60405190815260200160405180910390f35b610041610061366004612036565b6109e7565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101949190612176565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb6121fd565b0497505061030189602001518a60a00151611569565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611599565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61222c565b6040518563ffffffff1660e01b81526004016104db9493929190612298565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b505050506101008a01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190612176565b90508481108061076b57506107688986612389565b81105b156107a2576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c48b60c001518c61010001518d6080015161ffff168e602001518d61162b565b985085156108f35787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108ad576040519150601f19603f3d011682016040523d82523d6000602084013e6108b2565b606091505b50509050806108ed576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610927565b6109278b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b85610937578a610100015161093a565b60005b73ffffffffffffffffffffffffffffffffffffffff168761095f578b60e00151610962565b60005b73ffffffffffffffffffffffffffffffffffffffff168c60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38e600001518d6040516109d1929190918252602082015260400190565b60405180910390a4505050505050505092915050565b60008260c0015165ffffffffffff16421115610a2f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1092916000918291908290610a7557610a7561239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610ac657610ac661239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610ba4578761010001518481518110610b0557610b0561239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9f9190612176565b610ba6565b475b90506000610bc889604001518a600001518b61010001518c61012001516116e4565b9050610bdc89602001518a60800151611569565b8160018351610beb91906123cb565b81518110610bfb57610bfb61239c565b60200260200101511015610c3b576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610d725788513414610c7b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b5050505050610d6d896101200151600081518110610d1b57610d1b61239c565b60200260200101518a600001518b6101000151600081518110610d4057610d4061239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b610fc7565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610de157610de161239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610e87919061222c565b6040518563ffffffff1660e01b8152600401610ea69493929190612298565b600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610f1557610f1561239c565b60200260200101518c600001518d6101000151600081518110610f3a57610f3a61239c565b60200260200101516040518563ffffffff1660e01b8152600401610f94949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610fae57600080fd5b505af1158015610fc2573d6000803e3d6000fd5b505050505b60005b858110156111d0576000610fdf826001612389565b905060008b61010001518281518110610ffa57610ffa61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c6101000151848151811061102f5761102f61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061105957600061105c565b60015b9050600060028d61010001515161107391906123cb565b841061107f573061109f565b8c610120015183815181106110965761109661239c565b60200260200101515b90508c610120015184815181106110b8576110b861239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836110ff578685815181106110f2576110f261239c565b6020026020010151611102565b60005b8461110e576000611129565b8786815181106111205761112061239c565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156111a957600080fd5b505af11580156111bd573d6000803e3d6000fd5b505060019095019450610fca9350505050565b50600089610100015186815181106111ea576111ea61239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190612176565b90508281108061129c57506112998884612389565b81105b156112d3576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113278a60e001518b610100015188815181106112f2576112f261239c565b60200260200101518c60a0015161ffff168d60200151868b8151811061131a5761131a61239c565b602002602001015161162b565b975083156114565786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611410576040519150601f19603f3d011682016040523d82523d6000602084013e611415565b606091505b5050905080611450576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611476565b6114768a60600151898c61010001518981518110610d4057610d4061239c565b8361149f5789610100015186815181106114925761149261239c565b60200260200101516114a2565b60005b73ffffffffffffffffffffffffffffffffffffffff16856114e2578a61010001516000815181106114d5576114d561239c565b60200260200101516114e5565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60e0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c604051611554929190918252602082015260400190565b60405180910390a45050505050505092915050565b600061271061157883826123de565b6115869061ffff1685612400565b6115909190612417565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611626908490611919565b505050565b60006107d0841115611672576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611684575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116ba57606460328402046116bd565b60005b90508083038382146116d5576116d58a8a8484611a28565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561170457611704611cff565b60405190808252806020026020018201604052801561172d578160200160208202803683370190505b50915084826000815181106117445761174461239c565b60200260200101818152505060005b8181101561190f57600085828151811061176f5761176f61239c565b602002602001015190506000868360016117899190612389565b815181106117995761179961239c565b6020026020010151905060008984815181106117b7576117b761239c565b60200260200101516127106117cc91906123de565b61ffff1690506000808886815181106117e7576117e761239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185d91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156118b857905b828b0282612710020181848d0202816118d3576118d36121fd565b049a508a886118e3886001612389565b815181106118f3576118f361239c565b6020908102919091010152505060019093019250611753915050565b5050949350505050565b600061197b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611af09092919063ffffffff16565b905080516000148061199c57508080602001905181019061199c9190612452565b611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611669565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611aff8484600085611b07565b949350505050565b606082471015611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611669565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bc2919061249f565b60006040518083038185875af1925050503d8060008114611bff576040519150601f19603f3d011682016040523d82523d6000602084013e611c04565b606091505b5091509150611c1587838387611c20565b979650505050505050565b60608315611cb6578251600003611caf5773ffffffffffffffffffffffffffffffffffffffff85163b611caf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611669565b5081611aff565b611aff8383815115611ccb5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166991906124bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611d5257611d52611cff565b60405290565b604051610140810167ffffffffffffffff81118282101715611d5257611d52611cff565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc357611dc3611cff565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611def57600080fd5b919050565b803561ffff81168114611def57600080fd5b803565ffffffffffff81168114611def57600080fd5b600060408284031215611e2e57600080fd5b50919050565b600080828403610180811215611e4957600080fd5b61016080821215611e5957600080fd5b611e61611d2e565b91508435825260208501356020830152611e7d60408601611dcb565b6040830152611e8e60608601611dcb565b6060830152611e9f60808601611df4565b6080830152611eb060a08601611df4565b60a0830152611ec160c08601611dcb565b60c0830152611ed260e08601611dcb565b60e0830152610100611ee5818701611dcb565b90830152610120611ef7868201611df4565b90830152610140611f09868201611e06565b9083015290925083013567ffffffffffffffff811115611f2857600080fd5b611f3485828601611e1c565b9150509250929050565b600067ffffffffffffffff821115611f5857611f58611cff565b5060051b60200190565b600082601f830112611f7357600080fd5b81356020611f88611f8383611f3e565b611d7c565b82815260059290921b84018101918181019086841115611fa757600080fd5b8286015b84811015611fc957611fbc81611df4565b8352918301918301611fab565b509695505050505050565b600082601f830112611fe557600080fd5b81356020611ff5611f8383611f3e565b82815260059290921b8401810191818101908684111561201457600080fd5b8286015b84811015611fc95761202981611dcb565b8352918301918301612018565b6000806040838503121561204957600080fd5b823567ffffffffffffffff8082111561206157600080fd5b90840190610140828703121561207657600080fd5b61207e611d58565b823581526020830135602082015260408301358281111561209e57600080fd5b6120aa88828601611f62565b6040830152506120bc60608401611dcb565b60608201526120cd60808401611df4565b60808201526120de60a08401611df4565b60a08201526120ef60c08401611e06565b60c082015261210060e08401611dcb565b60e0820152610100808401358381111561211957600080fd5b61212589828701611fd4565b828401525050610120808401358381111561213f57600080fd5b61214b89828701611fd4565b82840152505080945050602085013591508082111561216957600080fd5b50611f3485828601611e1c565b60006020828403121561218857600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611def57600080fd5b6000806000606084860312156121c257600080fd5b6121cb8461218f565b92506121d96020850161218f565b9150604084015163ffffffff811681146121f257600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261226157600080fd5b83018035915067ffffffffffffffff82111561227c57600080fd5b60200191503681900382131561229157600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156115935761159361235a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b818103818111156115935761159361235a565b61ffff8281168282160390808211156123f9576123f961235a565b5092915050565b80820281158282048414176115935761159361235a565b60008261244d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561246457600080fd5b8151801515811461247457600080fd5b9392505050565b60005b8381101561249657818101518382015260200161247e565b50506000910152565b600082516124b181846020870161247b565b9190910192915050565b60208152600082518060208401526124da81604085016020870161247b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220200d00eba2c244bcc4394586e11bed52f1bde27d737f84e6823312ec945bdf2064736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611e34565b610066565b60405190815260200160405180910390f35b610041610061366004612036565b6109e7565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101949190612176565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb6121fd565b0497505061030189602001518a60a00151611569565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611599565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61222c565b6040518563ffffffff1660e01b81526004016104db9493929190612298565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b505050506101008a01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190612176565b90508481108061076b57506107688986612389565b81105b156107a2576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c48b60c001518c61010001518d6080015161ffff168e602001518d61162b565b985085156108f35787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108ad576040519150601f19603f3d011682016040523d82523d6000602084013e6108b2565b606091505b50509050806108ed576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610927565b6109278b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b85610937578a610100015161093a565b60005b73ffffffffffffffffffffffffffffffffffffffff168761095f578b60e00151610962565b60005b73ffffffffffffffffffffffffffffffffffffffff168c60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38e600001518d6040516109d1929190918252602082015260400190565b60405180910390a4505050505050505092915050565b60008260c0015165ffffffffffff16421115610a2f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1092916000918291908290610a7557610a7561239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610ac657610ac661239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610ba4578761010001518481518110610b0557610b0561239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9f9190612176565b610ba6565b475b90506000610bc889604001518a600001518b61010001518c61012001516116e4565b9050610bdc89602001518a60800151611569565b8160018351610beb91906123cb565b81518110610bfb57610bfb61239c565b60200260200101511015610c3b576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610d725788513414610c7b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b5050505050610d6d896101200151600081518110610d1b57610d1b61239c565b60200260200101518a600001518b6101000151600081518110610d4057610d4061239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b610fc7565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610de157610de161239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610e87919061222c565b6040518563ffffffff1660e01b8152600401610ea69493929190612298565b600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610f1557610f1561239c565b60200260200101518c600001518d6101000151600081518110610f3a57610f3a61239c565b60200260200101516040518563ffffffff1660e01b8152600401610f94949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610fae57600080fd5b505af1158015610fc2573d6000803e3d6000fd5b505050505b60005b858110156111d0576000610fdf826001612389565b905060008b61010001518281518110610ffa57610ffa61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c6101000151848151811061102f5761102f61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061105957600061105c565b60015b9050600060028d61010001515161107391906123cb565b841061107f573061109f565b8c610120015183815181106110965761109661239c565b60200260200101515b90508c610120015184815181106110b8576110b861239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836110ff578685815181106110f2576110f261239c565b6020026020010151611102565b60005b8461110e576000611129565b8786815181106111205761112061239c565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156111a957600080fd5b505af11580156111bd573d6000803e3d6000fd5b505060019095019450610fca9350505050565b50600089610100015186815181106111ea576111ea61239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190612176565b90508281108061129c57506112998884612389565b81105b156112d3576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113278a60e001518b610100015188815181106112f2576112f261239c565b60200260200101518c60a0015161ffff168d60200151868b8151811061131a5761131a61239c565b602002602001015161162b565b975083156114565786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611410576040519150601f19603f3d011682016040523d82523d6000602084013e611415565b606091505b5050905080611450576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611476565b6114768a60600151898c61010001518981518110610d4057610d4061239c565b8361149f5789610100015186815181106114925761149261239c565b60200260200101516114a2565b60005b73ffffffffffffffffffffffffffffffffffffffff16856114e2578a61010001516000815181106114d5576114d561239c565b60200260200101516114e5565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60e0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c604051611554929190918252602082015260400190565b60405180910390a45050505050505092915050565b600061271061157883826123de565b6115869061ffff1685612400565b6115909190612417565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611626908490611919565b505050565b60006107d0841115611672576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611684575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116ba57606460328402046116bd565b60005b90508083038382146116d5576116d58a8a8484611a28565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561170457611704611cff565b60405190808252806020026020018201604052801561172d578160200160208202803683370190505b50915084826000815181106117445761174461239c565b60200260200101818152505060005b8181101561190f57600085828151811061176f5761176f61239c565b602002602001015190506000868360016117899190612389565b815181106117995761179961239c565b6020026020010151905060008984815181106117b7576117b761239c565b60200260200101516127106117cc91906123de565b61ffff1690506000808886815181106117e7576117e761239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185d91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156118b857905b828b0282612710020181848d0202816118d3576118d36121fd565b049a508a886118e3886001612389565b815181106118f3576118f361239c565b6020908102919091010152505060019093019250611753915050565b5050949350505050565b600061197b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611af09092919063ffffffff16565b905080516000148061199c57508080602001905181019061199c9190612452565b611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611669565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611aff8484600085611b07565b949350505050565b606082471015611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611669565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bc2919061249f565b60006040518083038185875af1925050503d8060008114611bff576040519150601f19603f3d011682016040523d82523d6000602084013e611c04565b606091505b5091509150611c1587838387611c20565b979650505050505050565b60608315611cb6578251600003611caf5773ffffffffffffffffffffffffffffffffffffffff85163b611caf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611669565b5081611aff565b611aff8383815115611ccb5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166991906124bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611d5257611d52611cff565b60405290565b604051610140810167ffffffffffffffff81118282101715611d5257611d52611cff565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc357611dc3611cff565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611def57600080fd5b919050565b803561ffff81168114611def57600080fd5b803565ffffffffffff81168114611def57600080fd5b600060408284031215611e2e57600080fd5b50919050565b600080828403610180811215611e4957600080fd5b61016080821215611e5957600080fd5b611e61611d2e565b91508435825260208501356020830152611e7d60408601611dcb565b6040830152611e8e60608601611dcb565b6060830152611e9f60808601611df4565b6080830152611eb060a08601611df4565b60a0830152611ec160c08601611dcb565b60c0830152611ed260e08601611dcb565b60e0830152610100611ee5818701611dcb565b90830152610120611ef7868201611df4565b90830152610140611f09868201611e06565b9083015290925083013567ffffffffffffffff811115611f2857600080fd5b611f3485828601611e1c565b9150509250929050565b600067ffffffffffffffff821115611f5857611f58611cff565b5060051b60200190565b600082601f830112611f7357600080fd5b81356020611f88611f8383611f3e565b611d7c565b82815260059290921b84018101918181019086841115611fa757600080fd5b8286015b84811015611fc957611fbc81611df4565b8352918301918301611fab565b509695505050505050565b600082601f830112611fe557600080fd5b81356020611ff5611f8383611f3e565b82815260059290921b8401810191818101908684111561201457600080fd5b8286015b84811015611fc95761202981611dcb565b8352918301918301612018565b6000806040838503121561204957600080fd5b823567ffffffffffffffff8082111561206157600080fd5b90840190610140828703121561207657600080fd5b61207e611d58565b823581526020830135602082015260408301358281111561209e57600080fd5b6120aa88828601611f62565b6040830152506120bc60608401611dcb565b60608201526120cd60808401611df4565b60808201526120de60a08401611df4565b60a08201526120ef60c08401611e06565b60c082015261210060e08401611dcb565b60e0820152610100808401358381111561211957600080fd5b61212589828701611fd4565b828401525050610120808401358381111561213f57600080fd5b61214b89828701611fd4565b82840152505080945050602085013591508082111561216957600080fd5b50611f3485828601611e1c565b60006020828403121561218857600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611def57600080fd5b6000806000606084860312156121c257600080fd5b6121cb8461218f565b92506121d96020850161218f565b9150604084015163ffffffff811681146121f257600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261226157600080fd5b83018035915067ffffffffffffffff82111561227c57600080fd5b60200191503681900382131561229157600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156115935761159361235a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b818103818111156115935761159361235a565b61ffff8281168282160390808211156123f9576123f961235a565b5092915050565b80820281158282048414176115935761159361235a565b60008261244d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561246457600080fd5b8151801515811461247457600080fd5b9392505050565b60005b8381101561249657818101518382015260200161247e565b50506000910152565b600082516124b181846020870161247b565b9190910192915050565b60208152600082518060208401526124da81604085016020870161247b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220200d00eba2c244bcc4394586e11bed52f1bde27d737f84e6823312ec945bdf2064736f6c63430008130033", + "numDeployments": 6, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"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\":\"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\":\"uniswapV2LikeExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"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\":\"uniswapV2LikeExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\\n * NOTE: The tokens must already have been moved to the first pool\\n */\\n function uniswapV2LikeExactInputSingleInternal(\\n ExactInputSingleParams memory params\\n ) internal returns (uint256 amountOut) {\\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\\n } else {\\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\\n }\\n\\n return uniswapV2LikeExactInputSingleInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 the pool\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n params.pool,\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n\\n return uniswapV2LikeExactInputSingleInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputInternal(\\n ExactInputParams calldata params\\n ) internal returns (uint256 amountOut) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n address[] memory tokens = params.tokens;\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = tokens[0] == address(0);\\n bool isToEth = tokens[poolLength] == address(0);\\n\\n if (isFromEth) {\\n tokens[0] = address(s.weth);\\n }\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : tokens[0],\\n isToEth ? address(0) : tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokens[0] == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\\n }\\n\\n return uniswapV2LikeExactInputInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\n // Permit tokens / set allowance\\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n\\n return uniswapV2LikeExactInputInternal(params);\\n }\\n}\\n\",\"keccak256\":\"0x2264d60e017f7ec8aa13691a2cabd116d785824587c832a5cb8dbaa5336599c1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Like is ILibStarVault, ILibWarp {\\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 ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInputSinglePermit(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInputPermit(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x61257f389c4a69c463baafad1a008ed2e9d68936a7e4a2cbe5a0cdc60df61e40\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b5061299a806100206000396000f3fe60806040526004361061003f5760003560e01c806311f1fdef14610044578063baa8ed3514610076578063c83ee48414610089578063d1b72bc41461009c575b600080fd5b34801561005057600080fd5b5061006461005f366004612268565b6100bc565b60405190815260200160405180910390f35b6100646100843660046122b9565b610319565b6100646100973660046122e9565b61052d565b3480156100a857600080fd5b506100646100b736600461231e565b610766565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610126906101008c01908c016123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161015d6101608b016101408c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161018f61016089016101408a016123d2565b65ffffffffffff1690526101a660208701876123ed565b6040518563ffffffff1660e01b81526004016101c59493929190612459565b600060405180830381600087803b1580156101df57600080fd5b505af11580156101f3573d6000803e3d6000fd5b5050505061021e7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c785163361024e60808701606088016123a1565b8635610261610100890160e08a016123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102df57600080fd5b505af11580156102f3573d6000803e3d6000fd5b505050506103108380360381019061030b91906125ad565b610a0c565b90505b92915050565b600061032d610160830161014084016123d2565b65ffffffffffff1642111561036e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610381610100840160e085016123a1565b73ffffffffffffffffffffffffffffffffffffffff16036104d657348235146103d6576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561046257600080fd5b505af1158015610476573d6000803e3d6000fd5b50505050506104d182606001602081019061049191906123a1565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff169084356110ca565b61051b565b61051b336104ea60808501606086016123a1565b84356104fd610100870160e088016123a1565b73ffffffffffffffffffffffffffffffffffffffff169291906111a3565b61031361030b368490038401846125ad565b600061053f60e0830160c084016123d2565b65ffffffffffff16421115610580576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610590610100840184612679565b60008181106105a1576105a16126e1565b90506020020160208101906105b691906123a1565b73ffffffffffffffffffffffffffffffffffffffff16036106ef573482351461060b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561069757600080fd5b505af11580156106ab573d6000803e3d6000fd5b50505050506106ea828061012001906106c49190612679565b60008181106106d5576106d56126e1565b905060200201602081019061049191906123a1565b61075d565b61075d33610701610120850185612679565b6000818110610712576107126126e1565b905060200201602081019061072791906123a1565b8435610737610100870187612679565b6000818110610748576107486126e1565b90506020020160208101906104fd91906123a1565b61031382611207565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915260009173ffffffffffffffffffffffffffffffffffffffff1690632b67b5709033908060608101806107c96101008b018b612679565b60008181106107da576107da6126e1565b90506020020160208101906107ef91906123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161082460e08b0160c08c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161085460e0890160c08a016123d2565b65ffffffffffff16905261086b60208701876123ed565b6040518563ffffffff1660e01b815260040161088a9493929190612459565b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506108e37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633610911610120870187612679565b6000818110610922576109226126e1565b905060200201602081019061093791906123a1565b8635610947610100890189612679565b6000818110610958576109586126e1565b905060200201602081019061096d91906123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050505061031083611207565b60e08101516101008201516000917f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff918216159116158381610af8576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af39190612710565b610afa565b475b90508215610b2057835473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8115610b4557835473ffffffffffffffffffffffffffffffffffffffff166101008701525b600080876060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915087610100015173ffffffffffffffffffffffffffffffffffffffff168860e0015173ffffffffffffffffffffffffffffffffffffffff161115610c1f57905b610120880151885161ffff6127109283031691840290820290810190830281610c4a57610c4a612797565b04975050610c6088602001518960a00151611b42565b871015610c99576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1610610cde576000610ce1565b60015b9050886060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610d0e5789610d11565b60005b83610d1d576000610d1f565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015610d8957600080fd5b505af1158015610d9d573d6000803e3d6000fd5b505050506101008901516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190612710565b905084811080610e4f5750610e4c89866127f5565b81105b15610e86576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea88a60c001518b61010001518c6080015161ffff168d602001518d611b69565b98508515610fd75787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d8060008114610f91576040519150601f19603f3d011682016040523d82523d6000602084013e610f96565b606091505b5050905080610fd1576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061100b565b61100b8a604001518a8c610100015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b8561101b5789610100015161101e565b60005b73ffffffffffffffffffffffffffffffffffffffff1687611043578a60e00151611046565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518d6040516110b5929190918252602082015260400190565b60405180910390a45050505050505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261119e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c22565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161111c565b50505050565b60007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1081611239610100850185612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061127b92505050610120860186612679565b9050905060008073ffffffffffffffffffffffffffffffffffffffff16836000815181106112ab576112ab6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168484815181106112f7576112f76126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115611387578454845173ffffffffffffffffffffffffffffffffffffffff90911690859060009061134c5761134c6126e1565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008161143f578484815181106113a0576113a06126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143a9190612710565b611441565b475b905060006114d061145560408b018b612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508c3591508990506114996101208e018e612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d3192505050565b90506114ef60208a01356114ea60a08c0160808d01612808565b611b42565b81600183516114fe9190612823565b8151811061150e5761150e6126e1565b6020026020010151101561154e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8581101561176f5760006115668260016127f5565b9050600088828151811061157c5761157c6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168984815181106115ac576115ac6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106115d65760006115d9565b60015b9050600060028a516115eb9190612823565b84106115f7573061162a565b6116056101208e018e612679565b84818110611615576116156126e1565b905060200201602081019061162a91906123a1565b905061163a6101208e018e612679565b8581811061164a5761164a6126e1565b905060200201602081019061165f91906123a1565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361169e57868581518110611691576116916126e1565b60200260200101516116a1565b60005b846116ad5760006116c8565b8786815181106116bf576116bf6126e1565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561174857600080fd5b505af115801561175c573d6000803e3d6000fd5b5050600190950194506115519350505050565b506000868681518110611784576117846126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190612710565b905082811080611836575061183389846127f5565b81105b1561186d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d66118816101008c0160e08d016123a1565b888881518110611893576118936126e1565b60200260200101518c60a00160208101906118ae9190612808565b61ffff168d60200135868b815181106118c9576118c96126e1565b6020026020010151611b69565b98508315611a125787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561194957600080fd5b505af115801561195d573d6000803e3d6000fd5b506000925061197591505060808c0160608d016123a1565b73ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146119cc576040519150601f19603f3d011682016040523d82523d6000602084013e6119d1565b606091505b5050905080611a0c576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611a65565b611a65611a2560808c0160608d016123a1565b8a898981518110611a3857611a386126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b83611a8957868681518110611a7c57611a7c6126e1565b6020026020010151611a8c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685611ac75787600081518110611aba57611aba6126e1565b6020026020010151611aca565b60005b73ffffffffffffffffffffffffffffffffffffffff16611af16101008d0160e08e016123a1565b604080518e358152602081018e905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f391016110b5565b6000612710611b518382612836565b611b5f9061ffff1685612858565b610310919061286f565b60006107d0841115611bb0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611bc2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611bf85760646032840204611bfb565b60005b9050808303838214611c1357611c138a8a8484611f66565b50505090910395945050505050565b6000611c84826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661202e9092919063ffffffff16565b9050805160001480611ca5575080806020019051810190611ca591906128aa565b61119e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611ba7565b805182516060919067ffffffffffffffff811115611d5157611d5161251b565b604051908082528060200260200182016040528015611d7a578160200160208202803683370190505b5091508482600081518110611d9157611d916126e1565b60200260200101818152505060005b81811015611f5c576000858281518110611dbc57611dbc6126e1565b60200260200101519050600086836001611dd691906127f5565b81518110611de657611de66126e1565b602002602001015190506000898481518110611e0457611e046126e1565b6020026020010151612710611e199190612836565b61ffff169050600080888681518110611e3457611e346126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115611f0557905b828b0282612710020181848d020281611f2057611f20612797565b049a508a88611f308860016127f5565b81518110611f4057611f406126e1565b6020908102919091010152505060019093019250611da0915050565b5050949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061203d8484600085612045565b949350505050565b6060824710156120d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611ba7565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161210091906128f7565b60006040518083038185875af1925050503d806000811461213d576040519150601f19603f3d011682016040523d82523d6000602084013e612142565b606091505b50915091506121538783838761215e565b979650505050505050565b606083156121f45782516000036121ed5773ffffffffffffffffffffffffffffffffffffffff85163b6121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611ba7565b508161203d565b61203d83838151156122095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79190612913565b6000610160828403121561225057600080fd5b50919050565b60006040828403121561225057600080fd5b600080610180838503121561227c57600080fd5b612286848461223d565b915061016083013567ffffffffffffffff8111156122a357600080fd5b6122af85828601612256565b9150509250929050565b600061016082840312156122cc57600080fd5b610310838361223d565b6000610140828403121561225057600080fd5b6000602082840312156122fb57600080fd5b813567ffffffffffffffff81111561231257600080fd5b61203d848285016122d6565b6000806040838503121561233157600080fd5b823567ffffffffffffffff8082111561234957600080fd5b612355868387016122d6565b9350602085013591508082111561236b57600080fd5b506122af85828601612256565b803573ffffffffffffffffffffffffffffffffffffffff8116811461239c57600080fd5b919050565b6000602082840312156123b357600080fd5b61031082612378565b803565ffffffffffff8116811461239c57600080fd5b6000602082840312156123e457600080fd5b610310826123bc565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261242257600080fd5b83018035915067ffffffffffffffff82111561243d57600080fd5b60200191503681900382131561245257600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715612595577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803561ffff8116811461239c57600080fd5b600061016082840312156125c057600080fd5b6125c861254a565b82358152602083013560208201526125e260408401612378565b60408201526125f360608401612378565b60608201526126046080840161259b565b608082015261261560a0840161259b565b60a082015261262660c08401612378565b60c082015261263760e08401612378565b60e082015261010061264a818501612378565b9082015261012061265c84820161259b565b9082015261014061266e8482016123bc565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126ae57600080fd5b83018035915067ffffffffffffffff8211156126c957600080fd5b6020019150600581901b360382131561245257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561272257600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461239c57600080fd5b60008060006060848603121561275c57600080fd5b61276584612729565b925061277360208501612729565b9150604084015163ffffffff8116811461278c57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610313576103136127c6565b60006020828403121561281a57600080fd5b6103108261259b565b81810381811115610313576103136127c6565b61ffff828116828216039080821115612851576128516127c6565b5092915050565b8082028115828204841417610313576103136127c6565b6000826128a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156128bc57600080fd5b815180151581146128cc57600080fd5b9392505050565b60005b838110156128ee5781810151838201526020016128d6565b50506000910152565b600082516129098184602087016128d3565b9190910192915050565b60208152600082518060208401526129328160408501602087016128d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de44c59485b64a44309171bd5ec5a3aa82d4e9417058be7ee66435ce87ad82ed64736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003f5760003560e01c806311f1fdef14610044578063baa8ed3514610076578063c83ee48414610089578063d1b72bc41461009c575b600080fd5b34801561005057600080fd5b5061006461005f366004612268565b6100bc565b60405190815260200160405180910390f35b6100646100843660046122b9565b610319565b6100646100973660046122e9565b61052d565b3480156100a857600080fd5b506100646100b736600461231e565b610766565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610126906101008c01908c016123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161015d6101608b016101408c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161018f61016089016101408a016123d2565b65ffffffffffff1690526101a660208701876123ed565b6040518563ffffffff1660e01b81526004016101c59493929190612459565b600060405180830381600087803b1580156101df57600080fd5b505af11580156101f3573d6000803e3d6000fd5b5050505061021e7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c785163361024e60808701606088016123a1565b8635610261610100890160e08a016123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102df57600080fd5b505af11580156102f3573d6000803e3d6000fd5b505050506103108380360381019061030b91906125ad565b610a0c565b90505b92915050565b600061032d610160830161014084016123d2565b65ffffffffffff1642111561036e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610381610100840160e085016123a1565b73ffffffffffffffffffffffffffffffffffffffff16036104d657348235146103d6576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561046257600080fd5b505af1158015610476573d6000803e3d6000fd5b50505050506104d182606001602081019061049191906123a1565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff169084356110ca565b61051b565b61051b336104ea60808501606086016123a1565b84356104fd610100870160e088016123a1565b73ffffffffffffffffffffffffffffffffffffffff169291906111a3565b61031361030b368490038401846125ad565b600061053f60e0830160c084016123d2565b65ffffffffffff16421115610580576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610590610100840184612679565b60008181106105a1576105a16126e1565b90506020020160208101906105b691906123a1565b73ffffffffffffffffffffffffffffffffffffffff16036106ef573482351461060b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561069757600080fd5b505af11580156106ab573d6000803e3d6000fd5b50505050506106ea828061012001906106c49190612679565b60008181106106d5576106d56126e1565b905060200201602081019061049191906123a1565b61075d565b61075d33610701610120850185612679565b6000818110610712576107126126e1565b905060200201602081019061072791906123a1565b8435610737610100870187612679565b6000818110610748576107486126e1565b90506020020160208101906104fd91906123a1565b61031382611207565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915260009173ffffffffffffffffffffffffffffffffffffffff1690632b67b5709033908060608101806107c96101008b018b612679565b60008181106107da576107da6126e1565b90506020020160208101906107ef91906123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161082460e08b0160c08c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161085460e0890160c08a016123d2565b65ffffffffffff16905261086b60208701876123ed565b6040518563ffffffff1660e01b815260040161088a9493929190612459565b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506108e37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633610911610120870187612679565b6000818110610922576109226126e1565b905060200201602081019061093791906123a1565b8635610947610100890189612679565b6000818110610958576109586126e1565b905060200201602081019061096d91906123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050505061031083611207565b60e08101516101008201516000917f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff918216159116158381610af8576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af39190612710565b610afa565b475b90508215610b2057835473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8115610b4557835473ffffffffffffffffffffffffffffffffffffffff166101008701525b600080876060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915087610100015173ffffffffffffffffffffffffffffffffffffffff168860e0015173ffffffffffffffffffffffffffffffffffffffff161115610c1f57905b610120880151885161ffff6127109283031691840290820290810190830281610c4a57610c4a612797565b04975050610c6088602001518960a00151611b42565b871015610c99576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1610610cde576000610ce1565b60015b9050886060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610d0e5789610d11565b60005b83610d1d576000610d1f565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015610d8957600080fd5b505af1158015610d9d573d6000803e3d6000fd5b505050506101008901516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190612710565b905084811080610e4f5750610e4c89866127f5565b81105b15610e86576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea88a60c001518b61010001518c6080015161ffff168d602001518d611b69565b98508515610fd75787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d8060008114610f91576040519150601f19603f3d011682016040523d82523d6000602084013e610f96565b606091505b5050905080610fd1576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061100b565b61100b8a604001518a8c610100015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b8561101b5789610100015161101e565b60005b73ffffffffffffffffffffffffffffffffffffffff1687611043578a60e00151611046565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518d6040516110b5929190918252602082015260400190565b60405180910390a45050505050505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261119e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c22565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161111c565b50505050565b60007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1081611239610100850185612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061127b92505050610120860186612679565b9050905060008073ffffffffffffffffffffffffffffffffffffffff16836000815181106112ab576112ab6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168484815181106112f7576112f76126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115611387578454845173ffffffffffffffffffffffffffffffffffffffff90911690859060009061134c5761134c6126e1565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008161143f578484815181106113a0576113a06126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143a9190612710565b611441565b475b905060006114d061145560408b018b612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508c3591508990506114996101208e018e612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d3192505050565b90506114ef60208a01356114ea60a08c0160808d01612808565b611b42565b81600183516114fe9190612823565b8151811061150e5761150e6126e1565b6020026020010151101561154e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8581101561176f5760006115668260016127f5565b9050600088828151811061157c5761157c6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168984815181106115ac576115ac6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106115d65760006115d9565b60015b9050600060028a516115eb9190612823565b84106115f7573061162a565b6116056101208e018e612679565b84818110611615576116156126e1565b905060200201602081019061162a91906123a1565b905061163a6101208e018e612679565b8581811061164a5761164a6126e1565b905060200201602081019061165f91906123a1565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361169e57868581518110611691576116916126e1565b60200260200101516116a1565b60005b846116ad5760006116c8565b8786815181106116bf576116bf6126e1565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561174857600080fd5b505af115801561175c573d6000803e3d6000fd5b5050600190950194506115519350505050565b506000868681518110611784576117846126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190612710565b905082811080611836575061183389846127f5565b81105b1561186d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d66118816101008c0160e08d016123a1565b888881518110611893576118936126e1565b60200260200101518c60a00160208101906118ae9190612808565b61ffff168d60200135868b815181106118c9576118c96126e1565b6020026020010151611b69565b98508315611a125787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561194957600080fd5b505af115801561195d573d6000803e3d6000fd5b506000925061197591505060808c0160608d016123a1565b73ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146119cc576040519150601f19603f3d011682016040523d82523d6000602084013e6119d1565b606091505b5050905080611a0c576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611a65565b611a65611a2560808c0160608d016123a1565b8a898981518110611a3857611a386126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b83611a8957868681518110611a7c57611a7c6126e1565b6020026020010151611a8c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685611ac75787600081518110611aba57611aba6126e1565b6020026020010151611aca565b60005b73ffffffffffffffffffffffffffffffffffffffff16611af16101008d0160e08e016123a1565b604080518e358152602081018e905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f391016110b5565b6000612710611b518382612836565b611b5f9061ffff1685612858565b610310919061286f565b60006107d0841115611bb0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611bc2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611bf85760646032840204611bfb565b60005b9050808303838214611c1357611c138a8a8484611f66565b50505090910395945050505050565b6000611c84826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661202e9092919063ffffffff16565b9050805160001480611ca5575080806020019051810190611ca591906128aa565b61119e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611ba7565b805182516060919067ffffffffffffffff811115611d5157611d5161251b565b604051908082528060200260200182016040528015611d7a578160200160208202803683370190505b5091508482600081518110611d9157611d916126e1565b60200260200101818152505060005b81811015611f5c576000858281518110611dbc57611dbc6126e1565b60200260200101519050600086836001611dd691906127f5565b81518110611de657611de66126e1565b602002602001015190506000898481518110611e0457611e046126e1565b6020026020010151612710611e199190612836565b61ffff169050600080888681518110611e3457611e346126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115611f0557905b828b0282612710020181848d020281611f2057611f20612797565b049a508a88611f308860016127f5565b81518110611f4057611f406126e1565b6020908102919091010152505060019093019250611da0915050565b5050949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061203d8484600085612045565b949350505050565b6060824710156120d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611ba7565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161210091906128f7565b60006040518083038185875af1925050503d806000811461213d576040519150601f19603f3d011682016040523d82523d6000602084013e612142565b606091505b50915091506121538783838761215e565b979650505050505050565b606083156121f45782516000036121ed5773ffffffffffffffffffffffffffffffffffffffff85163b6121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611ba7565b508161203d565b61203d83838151156122095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79190612913565b6000610160828403121561225057600080fd5b50919050565b60006040828403121561225057600080fd5b600080610180838503121561227c57600080fd5b612286848461223d565b915061016083013567ffffffffffffffff8111156122a357600080fd5b6122af85828601612256565b9150509250929050565b600061016082840312156122cc57600080fd5b610310838361223d565b6000610140828403121561225057600080fd5b6000602082840312156122fb57600080fd5b813567ffffffffffffffff81111561231257600080fd5b61203d848285016122d6565b6000806040838503121561233157600080fd5b823567ffffffffffffffff8082111561234957600080fd5b612355868387016122d6565b9350602085013591508082111561236b57600080fd5b506122af85828601612256565b803573ffffffffffffffffffffffffffffffffffffffff8116811461239c57600080fd5b919050565b6000602082840312156123b357600080fd5b61031082612378565b803565ffffffffffff8116811461239c57600080fd5b6000602082840312156123e457600080fd5b610310826123bc565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261242257600080fd5b83018035915067ffffffffffffffff82111561243d57600080fd5b60200191503681900382131561245257600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715612595577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803561ffff8116811461239c57600080fd5b600061016082840312156125c057600080fd5b6125c861254a565b82358152602083013560208201526125e260408401612378565b60408201526125f360608401612378565b60608201526126046080840161259b565b608082015261261560a0840161259b565b60a082015261262660c08401612378565b60c082015261263760e08401612378565b60e082015261010061264a818501612378565b9082015261012061265c84820161259b565b9082015261014061266e8482016123bc565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126ae57600080fd5b83018035915067ffffffffffffffff8211156126c957600080fd5b6020019150600581901b360382131561245257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561272257600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461239c57600080fd5b60008060006060848603121561275c57600080fd5b61276584612729565b925061277360208501612729565b9150604084015163ffffffff8116811461278c57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610313576103136127c6565b60006020828403121561281a57600080fd5b6103108261259b565b81810381811115610313576103136127c6565b61ffff828116828216039080821115612851576128516127c6565b5092915050565b8082028115828204841417610313576103136127c6565b6000826128a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156128bc57600080fd5b815180151581146128cc57600080fd5b9392505050565b60005b838110156128ee5781810151838201526020016128d6565b50506000910152565b600082516129098184602087016128d3565b9190910192915050565b60208152600082518060208401526129328160408501602087016128d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de44c59485b64a44309171bd5ec5a3aa82d4e9417058be7ee66435ce87ad82ed64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/base/UniV3Callback.json b/packages/hardhat/deployments/base/UniV3Callback.json index 7c0772c3..ae8ed76c 100644 --- a/packages/hardhat/deployments/base/UniV3Callback.json +++ b/packages/hardhat/deployments/base/UniV3Callback.json @@ -1,5 +1,5 @@ { - "address": "0x12Ad749fbdCF48bBc2D4aDcD00f95BA99bd13b63", + "address": "0x6Eb7651D827818B2dfdbA80E1A33743dEc3Fc701", "abi": [ { "inputs": [], @@ -122,28 +122,28 @@ "type": "function" } ], - "transactionHash": "0xde6562455f2887b4d8f314492d9fad4096adc0aa563df13a2df91379d58ed701", + "transactionHash": "0xbab989aa28bf78c049ab2e82e148c54861b5b249dcdaea4af38de147b0b7e393", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x12Ad749fbdCF48bBc2D4aDcD00f95BA99bd13b63", - "transactionIndex": 10, - "gasUsed": "490767", + "contractAddress": "0x6Eb7651D827818B2dfdbA80E1A33743dEc3Fc701", + "transactionIndex": 1, + "gasUsed": "548027", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5286b6329428ae51cc3167ea18b09fa7edc08e67031859680374c3e4cd14fbaa", - "transactionHash": "0xde6562455f2887b4d8f314492d9fad4096adc0aa563df13a2df91379d58ed701", + "blockHash": "0xc64f2ee505e032eefcf2ef7745db9eeb563fc2e65d149b2edc8d6eea0b68e492", + "transactionHash": "0xbab989aa28bf78c049ab2e82e148c54861b5b249dcdaea4af38de147b0b7e393", "logs": [], - "blockNumber": 5413542, - "cumulativeGasUsed": "1334415", + "blockNumber": 6230659, + "cumulativeGasUsed": "594940", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "4a9aead708515414ed961374f1d066ed", - "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\":\"pancakeV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"ramsesV2SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swapCallback\",\"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\"},\"pancakeV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"ramsesV2SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"swapCallback(int256,int256,bytes)\":{\"notice\":\"KyperSwap V2 callback 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 /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * KyperSwap V2 callback\\n * NOTE: None of these arguments can be trusted\\n */\\n function swapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x85ecd0df604a102bbc22cbcfd07afec90fd4abb25b8fac2ce0bda48ba5663f82\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107f7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610687565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d5490911692820192909252903090036101c057805160408201516101bb9173ffffffffffffffffffffffffffffffffffffffff9091169033906102d2565b610288565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561026f57600080fd5b505af1158015610283573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261035f908490610364565b505050565b60006103c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104789092919063ffffffff16565b90508051600014806103e75750808060200190518101906103e79190610707565b61035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610487848460008561048f565b949350505050565b606082471015610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046f565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161054a9190610754565b60006040518083038185875af1925050503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d878383876105a8565b979650505050505050565b6060831561063e5782516000036106375773ffffffffffffffffffffffffffffffffffffffff85163b610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046f565b5081610487565b61048783838151156106535781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046f9190610770565b6000806000806060858703121561069d57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156106c357600080fd5b818701915087601f8301126106d757600080fd5b8135818111156106e657600080fd5b8860208285010111156106f857600080fd5b95989497505060200194505050565b60006020828403121561071957600080fd5b8151801515811461072957600080fd5b9392505050565b60005b8381101561074b578181015183820152602001610733565b50506000910152565b60008251610766818460208701610730565b9190910192915050565b602081526000825180602084015261078f816040850160208701610730565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e0c3a5ea77a59d4a136519a3fb790277ee65b84323dca008c9268c0208c1cb4364736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610687565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d5490911692820192909252903090036101c057805160408201516101bb9173ffffffffffffffffffffffffffffffffffffffff9091169033906102d2565b610288565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561026f57600080fd5b505af1158015610283573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261035f908490610364565b505050565b60006103c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104789092919063ffffffff16565b90508051600014806103e75750808060200190518101906103e79190610707565b61035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610487848460008561048f565b949350505050565b606082471015610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046f565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161054a9190610754565b60006040518083038185875af1925050503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d878383876105a8565b979650505050505050565b6060831561063e5782516000036106375773ffffffffffffffffffffffffffffffffffffffff85163b610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046f565b5081610487565b61048783838151156106535781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046f9190610770565b6000806000806060858703121561069d57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156106c357600080fd5b818701915087601f8301126106d757600080fd5b8135818111156106e657600080fd5b8860208285010111156106f857600080fd5b95989497505060200194505050565b60006020828403121561071957600080fd5b8151801515811461072957600080fd5b9392505050565b60005b8381101561074b578181015183820152602001610733565b50506000910152565b60008251610766818460208701610730565b9190910192915050565b602081526000825180602084015261078f816040850160208701610730565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e0c3a5ea77a59d4a136519a3fb790277ee65b84323dca008c9268c0208c1cb4364736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "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\":\"pancakeV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"ramsesV2SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swapCallback\",\"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\"},\"pancakeV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"ramsesV2SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"swapCallback(int256,int256,bytes)\":{\"notice\":\"KyperSwap V2 callback 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 if (callback.usePermit == 1) {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n } else {\\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\\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 /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * KyperSwap V2 callback\\n * NOTE: None of these arguments can be trusted\\n */\\n function swapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xe3eb6dae32a233cc02e3aa833b2a7bac774a3c9c2c11f6d8feae8745d976f4b6\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610903806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610793565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e546060820152903090036101e757805160408201516101e29173ffffffffffffffffffffffffffffffffffffffff909116903390610339565b6102ef565b80606001516001036102bf577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156102a257600080fd5b505af11580156102b6573d6000803e3d6000fd5b505050506102ef565b6020810151815160408301516102ef9273ffffffffffffffffffffffffffffffffffffffff909116913390610412565b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261040d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610470565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526100899085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161038b565b60006104d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166105849092919063ffffffff16565b90508051600014806104f35750808060200190518101906104f39190610813565b61040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610593848460008561059b565b949350505050565b60608247101561062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161057b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106569190610860565b60006040518083038185875af1925050503d8060008114610693576040519150601f19603f3d011682016040523d82523d6000602084013e610698565b606091505b50915091506106a9878383876106b4565b979650505050505050565b6060831561074a5782516000036107435773ffffffffffffffffffffffffffffffffffffffff85163b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057b565b5081610593565b610593838381511561075f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b919061087c565b600080600080606085870312156107a957600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156107cf57600080fd5b818701915087601f8301126107e357600080fd5b8135818111156107f257600080fd5b88602082850101111561080457600080fd5b95989497505060200194505050565b60006020828403121561082557600080fd5b8151801515811461083557600080fd5b9392505050565b60005b8381101561085757818101518382015260200161083f565b50506000910152565b6000825161087281846020870161083c565b9190910192915050565b602081526000825180602084015261089b81604085016020870161083c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bd61054b7d7be6361f4cde7d339ff2b4e90fc18022d2e43caaa86ef48c70f7df64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610793565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e546060820152903090036101e757805160408201516101e29173ffffffffffffffffffffffffffffffffffffffff909116903390610339565b6102ef565b80606001516001036102bf577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156102a257600080fd5b505af11580156102b6573d6000803e3d6000fd5b505050506102ef565b6020810151815160408301516102ef9273ffffffffffffffffffffffffffffffffffffffff909116913390610412565b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261040d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610470565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526100899085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161038b565b60006104d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166105849092919063ffffffff16565b90508051600014806104f35750808060200190518101906104f39190610813565b61040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610593848460008561059b565b949350505050565b60608247101561062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161057b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106569190610860565b60006040518083038185875af1925050503d8060008114610693576040519150601f19603f3d011682016040523d82523d6000602084013e610698565b606091505b50915091506106a9878383876106b4565b979650505050505050565b6060831561074a5782516000036107435773ffffffffffffffffffffffffffffffffffffffff85163b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057b565b5081610593565b610593838381511561075f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b919061087c565b600080600080606085870312156107a957600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156107cf57600080fd5b818701915087601f8301126107e357600080fd5b8135818111156107f257600080fd5b88602082850101111561080457600080fd5b95989497505060200194505050565b60006020828403121561082557600080fd5b8151801515811461083557600080fd5b9392505050565b60005b8381101561085757818101518382015260200161083f565b50506000910152565b6000825161087281846020870161083c565b9190910192915050565b602081526000825180602084015261089b81604085016020870161083c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bd61054b7d7be6361f4cde7d339ff2b4e90fc18022d2e43caaa86ef48c70f7df64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/base/UniV3Like.json b/packages/hardhat/deployments/base/UniV3Like.json index b8daddc5..f0db3ef8 100644 --- a/packages/hardhat/deployments/base/UniV3Like.json +++ b/packages/hardhat/deployments/base/UniV3Like.json @@ -1,5 +1,5 @@ { - "address": "0x71e0BD402c5C0B61dE1D224824c551fE0D623065", + "address": "0x1B1a2071353424d10A33fF3D6F9AC686c8B8dC20", "abi": [ { "inputs": [], @@ -136,6 +136,72 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV3LikeExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -208,7 +274,78 @@ "type": "tuple" } ], - "name": "uniswapV3LikeExactInput", + "name": "uniswapV3LikeExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV3LikeExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -296,7 +433,7 @@ "type": "tuple" } ], - "name": "uniswapV3LikeExactInputSingle", + "name": "uniswapV3LikeExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -304,32 +441,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0xadcb8b3920b787dcdbd43e350cd9cd41b7d7cc5980abeeb06d8bafbcec3749cf", + "transactionHash": "0x58d7f25f3956845e1ff8e4663d2ff893cbb92fa5efe9014914e4fbd79deeeda5", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x71e0BD402c5C0B61dE1D224824c551fE0D623065", - "transactionIndex": 14, - "gasUsed": "2039103", + "contractAddress": "0x1B1a2071353424d10A33fF3D6F9AC686c8B8dC20", + "transactionIndex": 5, + "gasUsed": "2135647", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5cd9f15d9716f945bd4638b16754486ce9019128f37c3db2805f451e899e5a52", - "transactionHash": "0xadcb8b3920b787dcdbd43e350cd9cd41b7d7cc5980abeeb06d8bafbcec3749cf", + "blockHash": "0xb3874ccdfec036205f6679b05794b3bf803c2d96e68c072ac7cf86bdf72006d6", + "transactionHash": "0x58d7f25f3956845e1ff8e4663d2ff893cbb92fa5efe9014914e4fbd79deeeda5", "logs": [], - "blockNumber": 5459504, - "cumulativeGasUsed": "4195563", + "blockNumber": 6230667, + "cumulativeGasUsed": "2597983", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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/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 {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokens[0],\\n isToEth ? address(0) : params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0778264b402de681401a9d1ca9ee9e1d313e2075b7d853b1504704a605ba6c23\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\\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\":\"0x61677478daa5f86ad18959bbe4a13b95a997853f844642be3f6eb54d6ab9a772\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612421806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611de2565b610066565b60405190815260200160405180910390f35b610041610061366004611f8f565b6109f6565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029291906120a9565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff1681525089806020019061045191906120c2565b6040518563ffffffff1660e01b8152600401610470949392919061212e565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e91906121f0565b9150508061057b90612243565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906121f0565b50905061066381612243565b9550505b61066f61173b565b610682876101000151886060015161179b565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906120a9565b9050828110806107685750610765868461227b565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c188602001518960e001518a6040015161ffff168b61010001518a6117cb565b95508315610910577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108ca576040519150601f19603f3d011682016040523d82523d6000602084013e6108cf565b606091505b505090508061090a576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061093a565b875160e089015161093a9173ffffffffffffffffffffffffffffffffffffffff9091169088611884565b83610949578760e0015161094c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685610971578860c00151610974565b60005b73ffffffffffffffffffffffffffffffffffffffff16896020015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38b608001518a6040516109e3929190918252602082015260400190565b60405180910390a4505050505092915050565b60008260a0015165ffffffffffff16421115610a3e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e0840151805160009182918290610a5f57610a5f61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e001518481518110610aaf57610aaf61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610add5733610adf565b305b90508215610bfd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610b3b57610b3b61228e565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610b9a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b5050505050505b8115610c90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610c5557610c5561228e565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610ca857610ca861228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906120a9565b88519650905083610ed3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610ddb57610ddb61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610e8191906120c2565b6040518563ffffffff1660e01b8152600401610ea0949392919061212e565b600060405180830381600087803b158015610eba57600080fd5b505af1158015610ece573d6000803e3d6000fd5b505050505b60005b858110156111c457600081600101905060008a60e001518281518110610efe57610efe61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610f3257610f3261228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610fbf60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610f9957610f9961228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b80156110b65760008b61010001518481518110610fde57610fde61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a191906121f0565b915050806110ae90612243565b9950506111b1565b60008b610100015184815181106110cf576110cf61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906121f0565b5090506111ad81612243565b9950505b6111b961173b565b503093509050610ed6565b506111d386896060015161179b565b86101561120c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e0015186815181106112245761122461228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561129a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112be91906120a9565b9050818110806112d657506112d3878361227b565b81105b1561130d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113478960c001518a60e00151888151811061132b5761132b61228e565b60200260200101518b6080015161ffff168c602001518b6117cb565b96508315611496577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156113da57600080fd5b505af11580156113ee573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611450576040519150601f19603f3d011682016040523d82523d6000602084013e611455565b606091505b5050905080611490576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506114e2565b6114e28960400151888b60e0015189815181106114b5576114b561228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166118849092919063ffffffff16565b8361150a578860e0015186815181106114fd576114fd61228e565b602002602001015161150d565b60005b73ffffffffffffffffffffffffffffffffffffffff168561154c578960e0015160008151811061153f5761153f61228e565b602002602001015161154f565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b6040516115be929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611630576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611799576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60006127106117aa83826122bd565b6117b89061ffff16856122df565b6117c291906122f6565b90505b92915050565b60006107d0841115611812576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611824575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561185a576064603284020461185d565b60005b9050808303838214611875576118758a8a8484611916565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526119119084906119de565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611a40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611aed9092919063ffffffff16565b9050805160001480611a61575080806020019051810190611a619190612331565b611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611809565b6060611afc8484600085611b04565b949350505050565b606082471015611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611809565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbf919061237e565b60006040518083038185875af1925050503d8060008114611bfc576040519150601f19603f3d011682016040523d82523d6000602084013e611c01565b606091505b5091509150611c1287838387611c1d565b979650505050505050565b60608315611cb3578251600003611cac5773ffffffffffffffffffffffffffffffffffffffff85163b611cac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611809565b5081611afc565b611afc8383815115611cc85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611809919061239a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b60405290565b604051610120810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d9d57600080fd5b919050565b803561ffff81168114611d9d57600080fd5b803565ffffffffffff81168114611d9d57600080fd5b600060408284031215611ddc57600080fd5b50919050565b600080828403610160811215611df757600080fd5b61014080821215611e0757600080fd5b611e0f611d2b565b9150611e1a85611d79565b8252611e2860208601611d79565b6020830152611e3960408601611da2565b6040830152611e4a60608601611da2565b606083015260808501356080830152611e6560a08601611db4565b60a0830152611e7660c08601611d79565b60c0830152611e8760e08601611d79565b60e08301526101008581013590830152610120611ea5818701611d79565b9083015290925083013567ffffffffffffffff811115611ec457600080fd5b611ed085828601611dca565b9150509250929050565b600082601f830112611eeb57600080fd5b8135602067ffffffffffffffff80831115611f0857611f08611cfc565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611f4b57611f4b611cfc565b604052938452858101830193838101925087851115611f6957600080fd5b83870191505b84821015611c1257611f8082611d79565b83529183019190830190611f6f565b60008060408385031215611fa257600080fd5b823567ffffffffffffffff80821115611fba57600080fd5b908401906101208287031215611fcf57600080fd5b611fd7611d55565b8235815260208301356020820152611ff160408401611d79565b604082015261200260608401611da2565b606082015261201360808401611da2565b608082015261202460a08401611db4565b60a082015261203560c08401611d79565b60c082015260e08301358281111561204c57600080fd5b61205888828601611eda565b60e083015250610100808401358381111561207257600080fd5b61207e89828701611eda565b82840152505080945050602085013591508082111561209c57600080fd5b50611ed085828601611dca565b6000602082840312156120bb57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120f757600080fd5b83018035915067ffffffffffffffff82111561211257600080fd5b60200191503681900382131561212757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561220357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361227457612274612214565b5060000390565b808201808211156117c5576117c5612214565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156122d8576122d8612214565b5092915050565b80820281158282048414176117c5576117c5612214565b60008261232c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561234357600080fd5b8151801515811461235357600080fd5b9392505050565b60005b8381101561237557818101518382015260200161235d565b50506000910152565b6000825161239081846020870161235a565b9190910192915050565b60208152600082518060208401526123b981604085016020870161235a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220576050a04e57b56eff16cf6c316bc8966ab4a176dcea2edf74c13dd26adc111164736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611de2565b610066565b60405190815260200160405180910390f35b610041610061366004611f8f565b6109f6565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029291906120a9565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff1681525089806020019061045191906120c2565b6040518563ffffffff1660e01b8152600401610470949392919061212e565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e91906121f0565b9150508061057b90612243565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906121f0565b50905061066381612243565b9550505b61066f61173b565b610682876101000151886060015161179b565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906120a9565b9050828110806107685750610765868461227b565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c188602001518960e001518a6040015161ffff168b61010001518a6117cb565b95508315610910577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108ca576040519150601f19603f3d011682016040523d82523d6000602084013e6108cf565b606091505b505090508061090a576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061093a565b875160e089015161093a9173ffffffffffffffffffffffffffffffffffffffff9091169088611884565b83610949578760e0015161094c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685610971578860c00151610974565b60005b73ffffffffffffffffffffffffffffffffffffffff16896020015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38b608001518a6040516109e3929190918252602082015260400190565b60405180910390a4505050505092915050565b60008260a0015165ffffffffffff16421115610a3e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e0840151805160009182918290610a5f57610a5f61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e001518481518110610aaf57610aaf61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610add5733610adf565b305b90508215610bfd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610b3b57610b3b61228e565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610b9a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b5050505050505b8115610c90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610c5557610c5561228e565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610ca857610ca861228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906120a9565b88519650905083610ed3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610ddb57610ddb61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610e8191906120c2565b6040518563ffffffff1660e01b8152600401610ea0949392919061212e565b600060405180830381600087803b158015610eba57600080fd5b505af1158015610ece573d6000803e3d6000fd5b505050505b60005b858110156111c457600081600101905060008a60e001518281518110610efe57610efe61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610f3257610f3261228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610fbf60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610f9957610f9961228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b80156110b65760008b61010001518481518110610fde57610fde61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a191906121f0565b915050806110ae90612243565b9950506111b1565b60008b610100015184815181106110cf576110cf61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906121f0565b5090506111ad81612243565b9950505b6111b961173b565b503093509050610ed6565b506111d386896060015161179b565b86101561120c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e0015186815181106112245761122461228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561129a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112be91906120a9565b9050818110806112d657506112d3878361227b565b81105b1561130d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113478960c001518a60e00151888151811061132b5761132b61228e565b60200260200101518b6080015161ffff168c602001518b6117cb565b96508315611496577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156113da57600080fd5b505af11580156113ee573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611450576040519150601f19603f3d011682016040523d82523d6000602084013e611455565b606091505b5050905080611490576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506114e2565b6114e28960400151888b60e0015189815181106114b5576114b561228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166118849092919063ffffffff16565b8361150a578860e0015186815181106114fd576114fd61228e565b602002602001015161150d565b60005b73ffffffffffffffffffffffffffffffffffffffff168561154c578960e0015160008151811061153f5761153f61228e565b602002602001015161154f565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b6040516115be929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611630576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611799576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60006127106117aa83826122bd565b6117b89061ffff16856122df565b6117c291906122f6565b90505b92915050565b60006107d0841115611812576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611824575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561185a576064603284020461185d565b60005b9050808303838214611875576118758a8a8484611916565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526119119084906119de565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611a40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611aed9092919063ffffffff16565b9050805160001480611a61575080806020019051810190611a619190612331565b611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611809565b6060611afc8484600085611b04565b949350505050565b606082471015611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611809565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbf919061237e565b60006040518083038185875af1925050503d8060008114611bfc576040519150601f19603f3d011682016040523d82523d6000602084013e611c01565b606091505b5091509150611c1287838387611c1d565b979650505050505050565b60608315611cb3578251600003611cac5773ffffffffffffffffffffffffffffffffffffffff85163b611cac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611809565b5081611afc565b611afc8383815115611cc85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611809919061239a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b60405290565b604051610120810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d9d57600080fd5b919050565b803561ffff81168114611d9d57600080fd5b803565ffffffffffff81168114611d9d57600080fd5b600060408284031215611ddc57600080fd5b50919050565b600080828403610160811215611df757600080fd5b61014080821215611e0757600080fd5b611e0f611d2b565b9150611e1a85611d79565b8252611e2860208601611d79565b6020830152611e3960408601611da2565b6040830152611e4a60608601611da2565b606083015260808501356080830152611e6560a08601611db4565b60a0830152611e7660c08601611d79565b60c0830152611e8760e08601611d79565b60e08301526101008581013590830152610120611ea5818701611d79565b9083015290925083013567ffffffffffffffff811115611ec457600080fd5b611ed085828601611dca565b9150509250929050565b600082601f830112611eeb57600080fd5b8135602067ffffffffffffffff80831115611f0857611f08611cfc565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611f4b57611f4b611cfc565b604052938452858101830193838101925087851115611f6957600080fd5b83870191505b84821015611c1257611f8082611d79565b83529183019190830190611f6f565b60008060408385031215611fa257600080fd5b823567ffffffffffffffff80821115611fba57600080fd5b908401906101208287031215611fcf57600080fd5b611fd7611d55565b8235815260208301356020820152611ff160408401611d79565b604082015261200260608401611da2565b606082015261201360808401611da2565b608082015261202460a08401611db4565b60a082015261203560c08401611d79565b60c082015260e08301358281111561204c57600080fd5b61205888828601611eda565b60e083015250610100808401358381111561207257600080fd5b61207e89828701611eda565b82840152505080945050602085013591508082111561209c57600080fd5b50611ed085828601611dca565b6000602082840312156120bb57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120f757600080fd5b83018035915067ffffffffffffffff82111561211257600080fd5b60200191503681900382131561212757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561220357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361227457612274612214565b5060000390565b808201808211156117c5576117c5612214565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156122d8576122d8612214565b5092915050565b80820281158282048414176117c5576117c5612214565b60008261232c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561234357600080fd5b8151801515811461235357600080fd5b9392505050565b60005b8381101561237557818101518382015260200161235d565b50506000910152565b6000825161239081846020870161235a565b9190910192915050565b60208152600082518060208401526123b981604085016020870161235a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220576050a04e57b56eff16cf6c316bc8966ab4a176dcea2edf74c13dd26adc111164736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"name\":\"uniswapV3LikeExactInput\",\"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\":\"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\":\"uniswapV3LikeExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"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\":\"uniswapV3LikeExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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/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 {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\\n ExactInputSingleParams calldata params,\\n uint256 usePermit\\n ) internal returns (uint256 amountOut) {\\n bool isFromEth = params.tokenIn == address(0);\\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\\n\\n address tokenOut = params.tokenOut == address(0)\\n ? address(LibWarp.state().weth)\\n : params.tokenOut;\\n\\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = tokenIn < tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: tokenIn,\\n amount: params.amountIn,\\n usePermit: usePermit\\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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (params.tokenOut == address(0)) {\\n // To ETH, unwrap WETH\\n // TODO: This is read twice. Compare gas usage\\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(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn == address(0)) {\\n // From ETH, wrap it\\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\\n }\\n\\n function uniswapV3LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\\n }\\n\\n function uniswapV3LikeExactInputInternal(\\n ExactInputParams calldata params,\\n uint256 usePermit\\n ) internal returns (uint256 amountOut) {\\n uint256 poolLength = params.pools.length;\\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\\n address[] memory tokens = params.tokens;\\n\\n if (params.tokens[0] == address(0)) {\\n tokens[0] = address(LibWarp.state().weth);\\n }\\n\\n if (params.tokens[poolLength] == address(0)) {\\n tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: payer,\\n token: tokens[index],\\n amount: amountOut,\\n usePermit: usePermit\\n })\\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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (params.tokens[poolLength] == address(0)) {\\n // To ETH, unwrap\\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n params.tokens[0],\\n params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokens[0] == address(0)) {\\n // From ETH, wrap it\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n }\\n\\n return uniswapV3LikeExactInputInternal(params, 0);\\n }\\n\\n function uniswapV3LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 return uniswapV3LikeExactInputInternal(params, 1);\\n }\\n}\\n\",\"keccak256\":\"0x9e23653ffdee1ddba14b812d0ed30da1b28d009e139fef4562407e722f5c541f\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\\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 calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x1fbea0694f83750cccdc1e2e316bc7466e7d04e7342fd7d4359459f056d30a71\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506125e1806100206000396000f3fe60806040526004361061003e5760003560e01c80626ee8b6146100435780635576abd114610068578063a33aea141461007b578063cda932d11461009b575b600080fd5b610056610051366004612064565b6100bb565b60405190815260200160405180910390f35b6100566100763660046120ac565b61024f565b34801561008757600080fd5b506100566100963660046120db565b6103b2565b3480156100a757600080fd5b506100566100b636600461212c565b6104fc565b60006100cd60c0830160a08401612186565b65ffffffffffff1642111561010e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061011d60e08401846121ae565b600081811061012e5761012e61221d565b9050602002016020810190610143919061224c565b73ffffffffffffffffffffffffffffffffffffffff160361023e5734823514610198576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b50505050505b61024982600061065b565b92915050565b600061026160c0830160a08401612186565b65ffffffffffff164211156102a2576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b460e0840160c0850161224c565b73ffffffffffffffffffffffffffffffffffffffff16036103a7577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660808301353414610344576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561038c57600080fd5b505af11580156103a0573d6000803e3d6000fd5b5050505050505b610249826000611118565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b57091339181906060820190819061041a908b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff908116825260808b013516602082015260400161045260c08b0160a08c01612186565b65ffffffffffff9081168252893516602091820152908252309082015260400161048260c0890160a08a01612186565b65ffffffffffff1690526104996020870187612282565b6040518563ffffffff1660e01b81526004016104b894939291906122e7565b600060405180830381600087803b1580156104d257600080fd5b505af11580156104e6573d6000803e3d6000fd5b505050506104f5836001611118565b9392505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610561908b018b6121ae565b60008181106105725761057261221d565b9050602002016020810190610587919061224c565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016105bc60c08b0160a08c01612186565b65ffffffffffff908116825289351660209182015290825230908201526040016105ec60c0890160a08a01612186565b65ffffffffffff1690526106036020870187612282565b6040518563ffffffff1660e01b815260040161062294939291906122e7565b600060405180830381600087803b15801561063c57600080fd5b505af1158015610650573d6000803e3d6000fd5b505050506104f58360015b60008061066c6101008501856121ae565b9150600090508061068060e08701876121ae565b60008181106106915761069161221d565b90506020020160208101906106a6919061224c565b73ffffffffffffffffffffffffffffffffffffffff16146106c757336106c9565b305b905060006106da60e08701876121ae565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061071b9250505060e08801886121ae565b600081811061072c5761072c61221d565b9050602002016020810190610741919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036107e5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff9091169082906000906107aa576107aa61221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f460e08801886121ae565b858181106108045761080461221d565b9050602002016020810190610819919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036108be577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff909116908290859081106108835761088361221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008184815181106108d2576108d261221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c91906123a9565b87359550905060005b84811015610c8157600081600101905060008482815181106109995761099961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168584815181106109c9576109c961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610a5860405180608001604052808a81526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878681518110610a2c57610a2c61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018b815250611904565b8015610b61576000610a6e6101008c018c6121ae565b85818110610a7e57610a7e61221d565b9050602002016020810190610a93919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c91906123c2565b91505080610b5990612415565b985050610c6e565b6000610b716101008c018c6121ae565b85818110610b8157610b8161221d565b9050602002016020810190610b96919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5e91906123c2565b509050610c6a81612415565b9850505b610c76611a93565b503094509050610975565b50610c9b85610c9660808a0160608b0161244d565b611af3565b851015610cd4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828581518110610ce857610ce861221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8291906123a9565b905081811080610d9a5750610d978683612471565b81105b15610dd1576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e20610de460e08a0160c08b0161224c565b848781518110610df657610df661221d565b60200260200101518a6080016020810190610e11919061244d565b61ffff168b602001358a611b1a565b95506000610e3160e08a018a6121ae565b87818110610e4157610e4161221d565b9050602002016020810190610e56919061224c565b73ffffffffffffffffffffffffffffffffffffffff1603610fc5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b5060009250610f2891505060608a0160408b0161224c565b73ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610f7f576040519150601f19603f3d011682016040523d82523d6000602084013e610f84565b606091505b5050905080610fbf576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611018565b611018610fd860608a0160408b0161224c565b87858881518110610feb57610feb61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611bd39092919063ffffffff16565b61102560e08901896121ae565b868181106110355761103561221d565b905060200201602081019061104a919061224c565b73ffffffffffffffffffffffffffffffffffffffff1661106d60e08a018a6121ae565b600081811061107e5761107e61221d565b9050602002016020810190611093919061224c565b73ffffffffffffffffffffffffffffffffffffffff166110b960e08b0160c08c0161224c565b604080518c358152602081018b905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050505092915050565b6000808061112c60e0860160c0870161224c565b73ffffffffffffffffffffffffffffffffffffffff161490506000816111615761115c60e0860160c0870161224c565b61119a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b90506000806111b0610100880160e0890161224c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576111dc610100870160e0880161224c565b61121a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae91906123a9565b905060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610905061134860405180608001604052808a608001358152602001876113065733611308565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200189815250611904565b80156114335760006113626101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b013560448201526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e91906123c2565b9150508061142b90612415565b965050611522565b60006114476101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b0135604482015273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151291906123c2565b50905061151e81612415565b9650505b61152a611a93565b611543610100890135610c9660808b0160608c0161244d565b86101561157c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d91906123a9565b90508281108061162557506116228784612471565b81105b1561165c576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61169061166f60408b0160208c0161224c565b8561168060608d0160408e0161244d565b61ffff168c61010001358b611b1a565b965060006116a56101008b0160e08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1603611811577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d80600081146117cb576040519150601f19603f3d011682016040523d82523d6000602084013e6117d0565b606091505b505090508061180b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061183f565b61183f61182160208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff86169089611bd3565b6118506101008a0160e08b0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661187660e08b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661189c60408c0160208d0161224c565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c608001358b6040516118f0929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611962576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611af1576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612710611b028382612484565b611b109061ffff16856124a6565b6104f591906124bd565b60006107d0841115611b61576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611b73575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611ba95760646032840204611bac565b60005b9050808303838214611bc457611bc48a8a8484611c65565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611c60908490611d2d565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611d8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e3c9092919063ffffffff16565b9050805160001480611db0575080806020019051810190611db091906124f8565b611c60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611b58565b6060611e4b8484600085611e53565b949350505050565b606082471015611ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611b58565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611f0e919061253e565b60006040518083038185875af1925050503d8060008114611f4b576040519150601f19603f3d011682016040523d82523d6000602084013e611f50565b606091505b5091509150611f6187838387611f6c565b979650505050505050565b60608315612002578251600003611ffb5773ffffffffffffffffffffffffffffffffffffffff85163b611ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611b58565b5081611e4b565b611e4b83838151156120175781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b58919061255a565b6000610120828403121561205e57600080fd5b50919050565b60006020828403121561207657600080fd5b813567ffffffffffffffff81111561208d57600080fd5b611e4b8482850161204b565b6000610140828403121561205e57600080fd5b600061014082840312156120bf57600080fd5b6104f58383612099565b60006040828403121561205e57600080fd5b60008061016083850312156120ef57600080fd5b6120f98484612099565b915061014083013567ffffffffffffffff81111561211657600080fd5b612122858286016120c9565b9150509250929050565b6000806040838503121561213f57600080fd5b823567ffffffffffffffff8082111561215757600080fd5b6121638683870161204b565b9350602085013591508082111561217957600080fd5b50612122858286016120c9565b60006020828403121561219857600080fd5b813565ffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126121e357600080fd5b83018035915067ffffffffffffffff8211156121fe57600080fd5b6020019150600581901b360382131561221657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561225e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122b757600080fd5b83018035915067ffffffffffffffff8211156122d257600080fd5b60200191503681900382131561221657600080fd5b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156123bb57600080fd5b5051919050565b600080604083850312156123d557600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203612446576124466123e6565b5060000390565b60006020828403121561245f57600080fd5b813561ffff811681146104f557600080fd5b80820180821115610249576102496123e6565b61ffff82811682821603908082111561249f5761249f6123e6565b5092915050565b8082028115828204841417610249576102496123e6565b6000826124f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561250a57600080fd5b815180151581146104f557600080fd5b60005b8381101561253557818101518382015260200161251d565b50506000910152565b6000825161255081846020870161251a565b9190910192915050565b602081526000825180602084015261257981604085016020870161251a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122020ef15a82dfe9e15884ad78a08e0e295c6c50a821511c6e99799a1a517eefc3564736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003e5760003560e01c80626ee8b6146100435780635576abd114610068578063a33aea141461007b578063cda932d11461009b575b600080fd5b610056610051366004612064565b6100bb565b60405190815260200160405180910390f35b6100566100763660046120ac565b61024f565b34801561008757600080fd5b506100566100963660046120db565b6103b2565b3480156100a757600080fd5b506100566100b636600461212c565b6104fc565b60006100cd60c0830160a08401612186565b65ffffffffffff1642111561010e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061011d60e08401846121ae565b600081811061012e5761012e61221d565b9050602002016020810190610143919061224c565b73ffffffffffffffffffffffffffffffffffffffff160361023e5734823514610198576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b50505050505b61024982600061065b565b92915050565b600061026160c0830160a08401612186565b65ffffffffffff164211156102a2576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b460e0840160c0850161224c565b73ffffffffffffffffffffffffffffffffffffffff16036103a7577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660808301353414610344576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561038c57600080fd5b505af11580156103a0573d6000803e3d6000fd5b5050505050505b610249826000611118565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b57091339181906060820190819061041a908b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff908116825260808b013516602082015260400161045260c08b0160a08c01612186565b65ffffffffffff9081168252893516602091820152908252309082015260400161048260c0890160a08a01612186565b65ffffffffffff1690526104996020870187612282565b6040518563ffffffff1660e01b81526004016104b894939291906122e7565b600060405180830381600087803b1580156104d257600080fd5b505af11580156104e6573d6000803e3d6000fd5b505050506104f5836001611118565b9392505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610561908b018b6121ae565b60008181106105725761057261221d565b9050602002016020810190610587919061224c565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016105bc60c08b0160a08c01612186565b65ffffffffffff908116825289351660209182015290825230908201526040016105ec60c0890160a08a01612186565b65ffffffffffff1690526106036020870187612282565b6040518563ffffffff1660e01b815260040161062294939291906122e7565b600060405180830381600087803b15801561063c57600080fd5b505af1158015610650573d6000803e3d6000fd5b505050506104f58360015b60008061066c6101008501856121ae565b9150600090508061068060e08701876121ae565b60008181106106915761069161221d565b90506020020160208101906106a6919061224c565b73ffffffffffffffffffffffffffffffffffffffff16146106c757336106c9565b305b905060006106da60e08701876121ae565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061071b9250505060e08801886121ae565b600081811061072c5761072c61221d565b9050602002016020810190610741919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036107e5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff9091169082906000906107aa576107aa61221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f460e08801886121ae565b858181106108045761080461221d565b9050602002016020810190610819919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036108be577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff909116908290859081106108835761088361221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008184815181106108d2576108d261221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c91906123a9565b87359550905060005b84811015610c8157600081600101905060008482815181106109995761099961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168584815181106109c9576109c961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610a5860405180608001604052808a81526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878681518110610a2c57610a2c61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018b815250611904565b8015610b61576000610a6e6101008c018c6121ae565b85818110610a7e57610a7e61221d565b9050602002016020810190610a93919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c91906123c2565b91505080610b5990612415565b985050610c6e565b6000610b716101008c018c6121ae565b85818110610b8157610b8161221d565b9050602002016020810190610b96919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5e91906123c2565b509050610c6a81612415565b9850505b610c76611a93565b503094509050610975565b50610c9b85610c9660808a0160608b0161244d565b611af3565b851015610cd4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828581518110610ce857610ce861221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8291906123a9565b905081811080610d9a5750610d978683612471565b81105b15610dd1576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e20610de460e08a0160c08b0161224c565b848781518110610df657610df661221d565b60200260200101518a6080016020810190610e11919061244d565b61ffff168b602001358a611b1a565b95506000610e3160e08a018a6121ae565b87818110610e4157610e4161221d565b9050602002016020810190610e56919061224c565b73ffffffffffffffffffffffffffffffffffffffff1603610fc5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b5060009250610f2891505060608a0160408b0161224c565b73ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610f7f576040519150601f19603f3d011682016040523d82523d6000602084013e610f84565b606091505b5050905080610fbf576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611018565b611018610fd860608a0160408b0161224c565b87858881518110610feb57610feb61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611bd39092919063ffffffff16565b61102560e08901896121ae565b868181106110355761103561221d565b905060200201602081019061104a919061224c565b73ffffffffffffffffffffffffffffffffffffffff1661106d60e08a018a6121ae565b600081811061107e5761107e61221d565b9050602002016020810190611093919061224c565b73ffffffffffffffffffffffffffffffffffffffff166110b960e08b0160c08c0161224c565b604080518c358152602081018b905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050505092915050565b6000808061112c60e0860160c0870161224c565b73ffffffffffffffffffffffffffffffffffffffff161490506000816111615761115c60e0860160c0870161224c565b61119a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b90506000806111b0610100880160e0890161224c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576111dc610100870160e0880161224c565b61121a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae91906123a9565b905060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610905061134860405180608001604052808a608001358152602001876113065733611308565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200189815250611904565b80156114335760006113626101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b013560448201526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e91906123c2565b9150508061142b90612415565b965050611522565b60006114476101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b0135604482015273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151291906123c2565b50905061151e81612415565b9650505b61152a611a93565b611543610100890135610c9660808b0160608c0161244d565b86101561157c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d91906123a9565b90508281108061162557506116228784612471565b81105b1561165c576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61169061166f60408b0160208c0161224c565b8561168060608d0160408e0161244d565b61ffff168c61010001358b611b1a565b965060006116a56101008b0160e08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1603611811577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d80600081146117cb576040519150601f19603f3d011682016040523d82523d6000602084013e6117d0565b606091505b505090508061180b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061183f565b61183f61182160208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff86169089611bd3565b6118506101008a0160e08b0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661187660e08b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661189c60408c0160208d0161224c565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c608001358b6040516118f0929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611962576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611af1576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612710611b028382612484565b611b109061ffff16856124a6565b6104f591906124bd565b60006107d0841115611b61576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611b73575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611ba95760646032840204611bac565b60005b9050808303838214611bc457611bc48a8a8484611c65565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611c60908490611d2d565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611d8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e3c9092919063ffffffff16565b9050805160001480611db0575080806020019051810190611db091906124f8565b611c60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611b58565b6060611e4b8484600085611e53565b949350505050565b606082471015611ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611b58565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611f0e919061253e565b60006040518083038185875af1925050503d8060008114611f4b576040519150601f19603f3d011682016040523d82523d6000602084013e611f50565b606091505b5091509150611f6187838387611f6c565b979650505050505050565b60608315612002578251600003611ffb5773ffffffffffffffffffffffffffffffffffffffff85163b611ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611b58565b5081611e4b565b611e4b83838151156120175781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b58919061255a565b6000610120828403121561205e57600080fd5b50919050565b60006020828403121561207657600080fd5b813567ffffffffffffffff81111561208d57600080fd5b611e4b8482850161204b565b6000610140828403121561205e57600080fd5b600061014082840312156120bf57600080fd5b6104f58383612099565b60006040828403121561205e57600080fd5b60008061016083850312156120ef57600080fd5b6120f98484612099565b915061014083013567ffffffffffffffff81111561211657600080fd5b612122858286016120c9565b9150509250929050565b6000806040838503121561213f57600080fd5b823567ffffffffffffffff8082111561215757600080fd5b6121638683870161204b565b9350602085013591508082111561217957600080fd5b50612122858286016120c9565b60006020828403121561219857600080fd5b813565ffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126121e357600080fd5b83018035915067ffffffffffffffff8211156121fe57600080fd5b6020019150600581901b360382131561221657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561225e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122b757600080fd5b83018035915067ffffffffffffffff8211156122d257600080fd5b60200191503681900382131561221657600080fd5b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156123bb57600080fd5b5051919050565b600080604083850312156123d557600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203612446576124466123e6565b5060000390565b60006020828403121561245f57600080fd5b813561ffff811681146104f557600080fd5b80820180821115610249576102496123e6565b61ffff82811682821603908082111561249f5761249f6123e6565b5092915050565b8082028115828204841417610249576102496123e6565b6000826124f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561250a57600080fd5b815180151581146104f557600080fd5b60005b8381101561253557818101518382015260200161251d565b50506000910152565b6000825161255081846020870161251a565b9190910192915050565b602081526000825180602084015261257981604085016020870161251a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122020ef15a82dfe9e15884ad78a08e0e295c6c50a821511c6e99799a1a517eefc3564736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/base/WarpLink.json b/packages/hardhat/deployments/base/WarpLink.json index 158c48d3..f21f4596 100644 --- a/packages/hardhat/deployments/base/WarpLink.json +++ b/packages/hardhat/deployments/base/WarpLink.json @@ -1,5 +1,5 @@ { - "address": "0xC28572E1a008760b204495AF30041da767F18d1B", + "address": "0xb80006779706b0f4FAd8D729B7a92b8Ca3bB6252", "abi": [ { "inputs": [], @@ -249,6 +249,71 @@ "stateMutability": "nonpayable", "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" + } + ], + "name": "warpLinkEngage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -326,34 +391,34 @@ "type": "tuple" } ], - "name": "warpLinkEngage", + "name": "warpLinkEngagePermit", "outputs": [], "stateMutability": "payable", "type": "function" } ], - "transactionHash": "0xe06fb8c24a5199080e2cf0cab22fb9bf920c74282e00c5340b47451afb215330", + "transactionHash": "0xcdb37233e656f7baf6d5a44c0cb26842230d5171f30e5e19146f263360c492b0", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xC28572E1a008760b204495AF30041da767F18d1B", - "transactionIndex": 2, - "gasUsed": "4672465", + "contractAddress": "0xb80006779706b0f4FAd8D729B7a92b8Ca3bB6252", + "transactionIndex": 1, + "gasUsed": "5125542", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4f58825a69cdabc2f25931b5663ebb9398381fb9391279c3bc2b730ecebaa698", - "transactionHash": "0xe06fb8c24a5199080e2cf0cab22fb9bf920c74282e00c5340b47451afb215330", + "blockHash": "0x64bf6a44492f4ea2f8146a8596948ff266fd11e0df81ae5f50dcf673d4764eda", + "transactionHash": "0xcdb37233e656f7baf6d5a44c0cb26842230d5171f30e5e19146f263360c492b0", "logs": [], - "blockNumber": 5795823, - "cumulativeGasUsed": "4990353", + "blockNumber": 6230676, + "cumulativeGasUsed": "5189555", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 6, - "solcInputHash": "62b3897f582f2743ff2d0ddfebde07d0", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"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\":\"InvalidSgReceiveSrcAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSgReceiverSender\",\"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\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"bytes\",\"name\":\"_srcAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountLD\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sgReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{\"sgReceive(uint16,bytes,uint256,address,uint256,bytes)\":{\"notice\":\"Cross-chain callback from Stargate The tokens have already been received by this contract, `t.payer` is set to this contract before `sgReceive` is called by the router. The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the same message more than once. The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the Stargate composer be compromised, an attacker can drain this contract. If the payload can not be decoded, tokens are left in this contract. If execution runs out of gas, tokens are left in this contract. If an error occurs during engage, such as insufficient output amount, tokens are refunded to the recipient. See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\"}},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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';\\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\\n bytes payload;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n address paramTokenIn;\\n uint256 paramAmountIn;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint48 paramDeadline;\\n uint256 amount;\\n address payer;\\n address token;\\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 useEth: isFromEth || isToEth,\\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 * Cross-chain callback from Stargate\\n *\\n * The tokens have already been received by this contract, `t.payer` is set to this contract\\n * before `sgReceive` is called by the router.\\n *\\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\\n * same message more than once.\\n *\\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\\n * Stargate composer be compromised, an attacker can drain this contract.\\n *\\n * If the payload can not be decoded, tokens are left in this contract.\\n * If execution runs out of gas, tokens are left in this contract.\\n *\\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\\n * to the recipient.\\n *\\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\\n */\\n function sgReceive(\\n uint16, // _srcChainId\\n bytes memory _srcAddress,\\n uint256, // _nonce\\n address _token,\\n uint256 amountLD,\\n bytes memory payload\\n ) external {\\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\\n revert InvalidSgReceiverSender();\\n }\\n\\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\\n // From https://ethereum.stackexchange.com/a/50528\\n address srcAddress;\\n\\n assembly {\\n srcAddress := mload(add(_srcAddress, 20))\\n }\\n\\n if (srcAddress != address(this)) {\\n // NOTE: This assumes that this contract is deployed at the same address on every chain\\n revert InvalidSgReceiveSrcAddress();\\n }\\n\\n Params memory params = abi.decode(payload, (Params));\\n\\n if (params.tokenIn == address(0)) {\\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\\n // otherwise because `_token` may be different on this chain\\n _token = address(0);\\n }\\n\\n try\\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\\n Params({\\n partner: params.partner,\\n feeBps: params.feeBps,\\n slippageBps: params.slippageBps,\\n recipient: params.recipient,\\n tokenIn: _token,\\n tokenOut: params.tokenOut,\\n amountIn: amountLD,\\n amountOut: params.amountOut,\\n deadline: params.deadline,\\n commands: params.commands\\n }),\\n PermitParams({nonce: 0, signature: ''})\\n )\\n {} catch {\\n // Refund tokens to the recipient\\n if (_token == address(0)) {\\n payable(params.recipient).transfer(amountLD);\\n } else {\\n IERC20(_token).safeTransfer(params.recipient, amountLD);\\n }\\n }\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\\n * in this function.\\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 * - dstGasForCall (uint32)\\n * - tokenOut (address) when `dstGasForCall` > 0\\n * - amountOut (uint256) when `dstGasForCall` > 0\\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n params.dstGasForCall = stream.readUint32();\\n\\n if (params.dstGasForCall > 0) {\\n // NOTE: `amountIn` is left as zero\\n Params memory destParams;\\n destParams.partner = t.paramPartner;\\n destParams.feeBps = t.paramFeeBps;\\n destParams.slippageBps = t.paramSlippageBps;\\n destParams.recipient = t.paramRecipient;\\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\\n // the same address as on this chain\\n destParams.tokenIn = t.token;\\n destParams.tokenOut = stream.readAddress();\\n destParams.amountOut = stream.readUint256();\\n destParams.deadline = t.paramDeadline;\\n destParams.commands = stream.readBytes();\\n params.payload = abi.encode(destParams);\\n }\\n\\n if (t.token != t.paramTokenIn) {\\n if (params.payload.length == 0) {\\n // If the tokens are being delivered directly to the recipient without a second\\n // WarpLink engage, the fee is charged on this chain\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibStarVault.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n }\\n\\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\\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. When there is a payload, the composer is used, else the router\\n IERC20(t.token).forceApprove(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\\n t.amount\\n );\\n }\\n\\n t.jumped = 1;\\n\\n // Swap on the composer if there is a payload, else the router\\n IStargateRouter(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\\n ).swap{\\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\\n }({\\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\\n // more on the other chain. It also assumes the tokens are of nearly equal value\\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: params.dstGasForCall,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n // NOTE: This assumes the contract is deployed at the same address on every chain.\\n // If this is not the case, a new param needs to be added with the next WarpLink address\\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\\n _payload: params.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.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\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 // The signature is omitted when `warpLinkEngage` is called from `sgReceive`\\n if (permit.signature.length > 0) {\\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\\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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0x198e2bb767f975464f62ecb8578721d7516f8da1302b3acfd3c622258de1320e\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\\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 error InvalidSgReceiverSender();\\n error InvalidSgReceiveSrcAddress();\\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\":\"0xc1d8b9ba2a1f8300c00adc2c66fd51da23bb40db78ce5b7fe270bb7ee77e923e\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IStargateReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\n\\ninterface IStargateReceiver {\\n function sgReceive(\\n uint16 _srcChainId, // the remote chainId sending the tokens\\n bytes memory _srcAddress, // the remote Bridge address\\n uint256 _nonce,\\n address _token, // the token contract on the local chain\\n uint256 amountLD, // the qty of local _token contract tokens\\n bytes memory payload\\n ) external;\\n}\\n\",\"keccak256\":\"0x7fd06c09139156a4f09a77eac28e453a1d2041a8cf01a108fc875c65192cb637\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50615400806100206000396000f3fe6080604052600436106100295760003560e01c8063ab8236f31461002e578063dc7b39db14610050575b600080fd5b34801561003a57600080fd5b5061004e610049366004614a1e565b610063565b005b61004e61005e366004614af2565b61036f565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff1633146100d6576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461012a576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906101409190614c9f565b608081015190915073ffffffffffffffffffffffffffffffffffffffff1661016757600094505b3063dc7b39db73ffffffffffffffffffffffffffffffffffffffff871615610190576000610192565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff168152602001856101200151815250604051806040016040528060008152602001604051806020016040528060008152508152506040518463ffffffff1660e01b81526004016102a4929190614efc565b6000604051808303818588803b1580156102bd57600080fd5b505af1935050505080156102cf575060015b6103655773ffffffffffffffffffffffffffffffffffffffff851661033e57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610338573d6000803e3d6000fd5b50610365565b60608101516103659073ffffffffffffffffffffffffffffffffffffffff87169086610981565b5050505050505050565b81610100015165ffffffffffff164211156103b6576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015161ffff9081169184019190915260408086018051831660c08087019182526060808a01518716948801949094526080808a01805188169589019590955290890180519188019190915260e0808a015160a0890152925190941690526101008088015165ffffffffffff169186019190915291519184019190915280518216610140840152511661052a578260c00151341015610509576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08301516105189034614f63565b610180820152306101208201526106bd565b336101208201523461018082015260006105476020840184614f76565b905011156106bd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff1681525085806020019061066b9190614f76565b6040518563ffffffff1660e01b815260040161068a9493929190614fe2565b600060405180830381600087803b1580156106a457600080fd5b505af11580156106b8573d6000803e3d6000fd5b505050505b60006106e2846101200151604080518082019091528181528151909101602082015290565b90506106ee8183610a5a565b61010081015161014082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610755576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107678660e001518760400151610c37565b8210156107a0576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361016001516001036107b557505050505050565b6107d686600001518760a00151886020015161ffff168960e0015186610c65565b915081600003610812576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661087d57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610877573d6000803e3d6000fd5b506108a4565b60608601516108a49073ffffffffffffffffffffffffffffffffffffffff83169084610981565b610180840151156108e257610180840151604051339180156108fc02916000818181858888f193505050501580156108e0573d6000803e3d6000fd5b505b8560a0015173ffffffffffffffffffffffffffffffffffffffff16866080015173ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c0015186604051610971929190918252602082015260400190565b60405180910390a4505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610d1e565b505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526000610ad58480516001018051915290565b60ff16905060005b81811015610c2b576000610af78680516001018051915290565b60ff16905060018103610b1457610b0d85610e2d565b9450610c18565b60028103610b2557610b0d85610ff5565b60038103610b3757610b0d8686611254565b60048103610b4957610b0d8686611832565b60058103610b5b57610b0d8686611bb9565b60068103610b6d57610b0d8686612367565b60078103610b7f57610b0d8686612891565b60088103610b9157610b0d8686612dcf565b60098103610be657610ba4600184614f63565b8214610bdc576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d8686613205565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5080610c23816150a4565b915050610add565b50829150505b92915050565b6000612710610c4683826150dc565b610c549061ffff16856150f7565b610c5e919061513d565b9392505050565b60006107d0841115610cac576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610cbe575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610cf45760646032840204610cf7565b60005b9050808303838214610d0f57610d0f8a8a84846139d7565b50505090910395945050505050565b6000610d80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613a9f9092919063ffffffff16565b9050805160001480610da1575080806020019051810190610da19190615178565b610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ca3565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408082018390526101608201839052610180820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610f0a576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014610f5e576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50959695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146110db576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff8116301480159061110957306101208601525b600061014086015280156111bc57600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505050505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916112199160040190815260200190565b600060405180830381600087803b15801561123357600080fd5b505af1158015611247573d6000803e3d6000fd5b5096979650505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff1661130f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff90911603611404576113ff816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b6114e0565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156114c057600080fd5b505af11580156114d4573d6000803e3d6000fd5b50503061012086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161158657905b606083015161010086015161ffff61271092830316918402908202908101908302816115b4576115b461510e565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e9190615208565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161168457876101000151611687565b60005b866040015161169757600061169e565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561170857600080fd5b505af115801561171c573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b49190615208565b9050818110806117d257506101008701516117cf9083615221565b81105b15611809576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915260006118ad8480516001018051915290565b60ff16905060008361010001519050600060028310156118f9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611b84576000611914600188614f63565b82106119205785611951565b6127106119338b80516002018051915290565b61ffff168a610100015161194791906150f7565b611951919061513d565b90508581111561198d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119978187614f63565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261012080820183815261014080840185815261016085018690526101808501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d015116909152909650611a368b82610a5a565b9050806101600151600103611a77576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611a945780610120015193508061014001519450611b68565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614611afe576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614611b68576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100810151611b789087615221565b955050506001016118ff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152611c4660405180606001604052806060815260200160608152602001606081525090565b6000611c588580516001018051915290565b60ff169050611c68816001615221565b67ffffffffffffffff811115611c8057611c806148ad565b604051908082528060200260200182016040528015611ca9578160200160208202803683370190505b508083526101408501518151909190600090611cc757611cc7615234565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b81811015611d6057855160140180519087528351611d23836001615221565b81518110611d3357611d33615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611d04565b50611d6b8582613ab6565b6020830152611d7a8582613b58565b6040830152815180516000919083908110611d9757611d97615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e319190615208565b90506000611e52846040015187610100015186600001518760200151613be1565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff1603611ee457611edf8460200151600081518110611ea657611ea6615234565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b611fe3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c78516929190600090611f4357611f43615234565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b8152600401611fa9949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015611fc357600080fd5b505af1158015611fd7573d6000803e3d6000fd5b50503061012089015250505b60005b838110156121e7576000611ffb826001615221565b905060008660000151828151811061201557612015615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168760000151848151811061204957612049615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612073576000612076565b60015b90506000600288600001515161208c9190614f63565b841061209857306120b7565b876020015183815181106120ae576120ae615234565b60200260200101515b9050876020015184815181106120cf576120cf615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836121165786858151811061210957612109615234565b6020026020010151612119565b60005b84612125576000612140565b87868151811061213757612137615234565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156121c057600080fd5b505af11580156121d4573d6000803e3d6000fd5b505060019095019450611fe69350505050565b5060008460000151848151811061220057612200615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229a9190615208565b905081600183516122ab9190614f63565b815181106122bb576122bb615234565b602002602001015187610100018181525050828110806122e957506101008701516122e69084615221565b81105b15612320576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845180518590811061233457612334615234565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff90811660208301526101408401511661247a576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156124e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250c9190615208565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff161090506125a86040518060600160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff16815250613e16565b801561268c5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561264f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126739190615263565b9150508061268090615287565b61010087015250612774565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561273c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127609190615263565b50905061276c81615287565b610100870152505b61277c613f7f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e9190615208565b90508281108061282c57506101008601516128299084615221565b81105b15612863576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261291e60405180606001604052806060815260200160608152602001606081525090565b60006129308580516001018051915290565b60ff16905061293f8582613ab6565b825261294b8582613ab6565b60208301528151600090612960600184614f63565b8151811061297057612970615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156129eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0f9190615208565b905060005b83811015612cd75760008115612a4e578551612a31600184614f63565b81518110612a4157612a41615234565b6020026020010151612a55565b8761014001515b905085600001518281518110612a6d57612a6d615234565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516060810182526101008d015181526101208d01518416948101949094529184169183018290521190612ace90613e16565b82600003612ade57306101208a01525b600087602001518481518110612af657612af6615234565b602002602001015190508115612be0576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc79190615263565b91505080612bd490615287565b6101008c015250612cc4565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb09190615263565b509050612cbc81615287565b6101008c0152505b612ccc613f7f565b505050600101612a14565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6e9190615208565b905081811080612d8c5750610100870151612d899083615221565b81105b15612dc3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff9283161592918216159130911614613006577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612fe657600080fd5b505af1158015612ffa573d6000803e3d6000fd5b50503061012088015250505b6000816130a35783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561307a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309e9190615208565b6130a5565b475b9050826130e5576130e5846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff16613fdf9092919063ffffffff16565b61312a84608001518560a0015186602001518661310357600061310a565b8961010001515b886040015189606001518c610100015160008b8061312557508a5b6140d5565b6000826131c75784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561319e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c29190615208565b6131c9565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506131f38282614f63565b61010088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526132a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613431576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff166101008201528451602080820180519092010186526101208201526040516133fc9082906020016152bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613543578060800151516000036134a5578251610140840151602085015161010086015161349e93929161ffff169080610c65565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3866080015187610100015160405161353a929190918252602082015260400190565b60405180910390a45b6135558360a001518460c00151610c37565b8361010001511015613593576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff91821691161561377f5761012084015173ffffffffffffffffffffffffffffffffffffffff1630146136d1577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156136b157600080fd5b505af11580156136c5573d6000803e3d6000fd5b50503061012087015250505b61377f8260800151516000146136e75781613756565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613732573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061375691906152d2565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff169190613fdf565b6001610160850152608082015151156137985780613807565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380791906152d2565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff16146138665785610180015161387c565b85610180015186610100015161387c9190615221565b8451602086015160408701516101008a015160c08b01513091906138a1908290610c37565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c6080015151116138e7578d604001516138e9565b305b604051602001613924919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b16835261399499989796959493926004016152ef565b6000604051808303818588803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b5050600061018088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060613aae84846000856145d1565b949350505050565b60608167ffffffffffffffff811115613ad157613ad16148ad565b604051908082528060200260200182016040528015613afa578160200160208202803683370190505b50905060005b82811015613b515783516014018051908552828281518110613b2457613b24615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613b00565b5092915050565b60608167ffffffffffffffff811115613b7357613b736148ad565b604051908082528060200260200182016040528015613b9c578160200160208202803683370190505b50905060005b82811015613b515783516002018051908552828281518110613bc657613bc6615234565b61ffff90921660209283029190910190910152600101613ba2565b805182516060919067ffffffffffffffff811115613c0157613c016148ad565b604051908082528060200260200182016040528015613c2a578160200160208202803683370190505b5091508482600081518110613c4157613c41615234565b60200260200101818152505060005b81811015613e0c576000858281518110613c6c57613c6c615234565b60200260200101519050600086836001613c869190615221565b81518110613c9657613c96615234565b602002602001015190506000898481518110613cb457613cb4615234565b6020026020010151612710613cc991906150dc565b61ffff169050600080888681518110613ce457613ce4615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d5a91906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115613db557905b828b0282612710020181848d020281613dd057613dd061510e565b049a508a88613de0886001615221565b81518110613df057613df0615234565b6020908102919091010152505060019093019250613c50915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613e74576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613fdd576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261406b84826146ea565b6140cf5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526140c59085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109d3565b6140cf8482610d1e565b50505050565b8860ff1660010361420357871561418e576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561417057600080fd5b505af1158015614184573d6000803e3d6000fd5b50505050506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614157565b8860ff166002036143435787156142ce576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156142a3573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906142c89190615208565b506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614285565b8860ff166003036144e45787156143c1576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614285565b801561443b576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614285565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af11580156144c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c89190615208565b8860ff16600403614594578715614527576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614157565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b606082471015614663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ca3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161468c919061539b565b60006040518083038185875af1925050503d80600081146146c9576040519150601f19603f3d011682016040523d82523d6000602084013e6146ce565b606091505b50915091506146df878383876147ab565b979650505050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614714919061539b565b6000604051808303816000865af19150503d8060008114614751576040519150601f19603f3d011682016040523d82523d6000602084013e614756565b606091505b50915091508180156147805750805115806147805750808060200190518101906147809190615178565b80156147a2575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060831561484157825160000361483a5773ffffffffffffffffffffffffffffffffffffffff85163b61483a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca3565b5081613aae565b613aae83838151156148565781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca391906153b7565b61ffff8116811461489a57600080fd5b50565b80356148a88161488a565b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614900576149006148ad565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561494d5761494d6148ad565b604052919050565b600067ffffffffffffffff82111561496f5761496f6148ad565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149ac57600080fd5b81356149bf6149ba82614955565b614906565b8181528460208386010111156149d457600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461489a57600080fd5b80356148a8816149f1565b60008060008060008060c08789031215614a3757600080fd5b8635614a428161488a565b9550602087013567ffffffffffffffff80821115614a5f57600080fd5b614a6b8a838b0161499b565b96506040890135955060608901359150614a84826149f1565b9093506080880135925060a08801359080821115614aa157600080fd5b50614aae89828a0161499b565b9150509295509295509295565b65ffffffffffff8116811461489a57600080fd5b80356148a881614abb565b600060408284031215614aec57600080fd5b50919050565b60008060408385031215614b0557600080fd5b823567ffffffffffffffff80821115614b1d57600080fd5b908401906101408287031215614b3257600080fd5b614b3a6148dc565b614b4383614a13565b8152614b516020840161489d565b6020820152614b626040840161489d565b6040820152614b7360608401614a13565b6060820152614b8460808401614a13565b6080820152614b9560a08401614a13565b60a082015260c083013560c082015260e083013560e0820152610100614bbc818501614acf565b908201526101208381013583811115614bd457600080fd5b614be08982870161499b565b828401525050809450506020850135915080821115614bfe57600080fd5b50614c0b85828601614ada565b9150509250929050565b80516148a8816149f1565b80516148a88161488a565b80516148a881614abb565b60005b83811015614c51578181015183820152602001614c39565b50506000910152565b600082601f830112614c6b57600080fd5b8151614c796149ba82614955565b818152846020838601011115614c8e57600080fd5b613aae826020830160208701614c36565b600060208284031215614cb157600080fd5b815167ffffffffffffffff80821115614cc957600080fd5b908301906101408286031215614cde57600080fd5b614ce66148dc565b614cef83614c15565b8152614cfd60208401614c20565b6020820152614d0e60408401614c20565b6040820152614d1f60608401614c15565b6060820152614d3060808401614c15565b6080820152614d4160a08401614c15565b60a082015260c083015160c082015260e083015160e0820152610100614d68818501614c2b565b908201526101208381015183811115614d8057600080fd5b614d8c88828701614c5a565b918301919091525095945050505050565b60008151808452614db5816020860160208601614c36565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006101406020830151614e1b602086018261ffff169052565b506040830151614e31604086018261ffff169052565b506060830151614e59606086018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151614e81608086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614ea960a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015160c085015260e083015160e085015261010080840151614ed88287018265ffffffffffff169052565b5050610120808401518282870152614ef283870182614d9d565b9695505050505050565b604081526000614f0f6040830185614de7565b828103602084015283518152602084015160406020830152614ef26040830182614d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c3157610c31614f34565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614fab57600080fd5b83018035915067ffffffffffffffff821115614fc657600080fd5b602001915036819003821315614fdb57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150d5576150d5614f34565b5060010190565b61ffff828116828216039080821115613b5157613b51614f34565b8082028115828204841417610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615173577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561518a57600080fd5b81518015158114610c5e57600080fd5b80516dffffffffffffffffffffffffffff811681146148a857600080fd5b6000806000606084860312156151cd57600080fd5b6151d68461519a565b92506151e46020850161519a565b9150604084015163ffffffff811681146151fd57600080fd5b809150509250925092565b60006020828403121561521a57600080fd5b5051919050565b80820180821115610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561527657600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036152b8576152b8614f34565b5060000390565b602081526000610c5e6020830184614de7565b6000602082840312156152e457600080fd5b8151610c5e816149f1565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615362610180840182614d9d565b905082810360e08401526153768186614d9d565b905082810361010084015261538b8185614d9d565b9c9b505050505050505050505050565b600082516153ad818460208701614c36565b9190910192915050565b602081526000610c5e6020830184614d9d56fea26469706673582212204eecdc76d361ea4a608ec1291a66f39b61f591d844e03c8f4164adb5e8c419c464736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c8063ab8236f31461002e578063dc7b39db14610050575b600080fd5b34801561003a57600080fd5b5061004e610049366004614a1e565b610063565b005b61004e61005e366004614af2565b61036f565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff1633146100d6576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461012a576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906101409190614c9f565b608081015190915073ffffffffffffffffffffffffffffffffffffffff1661016757600094505b3063dc7b39db73ffffffffffffffffffffffffffffffffffffffff871615610190576000610192565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff168152602001856101200151815250604051806040016040528060008152602001604051806020016040528060008152508152506040518463ffffffff1660e01b81526004016102a4929190614efc565b6000604051808303818588803b1580156102bd57600080fd5b505af1935050505080156102cf575060015b6103655773ffffffffffffffffffffffffffffffffffffffff851661033e57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610338573d6000803e3d6000fd5b50610365565b60608101516103659073ffffffffffffffffffffffffffffffffffffffff87169086610981565b5050505050505050565b81610100015165ffffffffffff164211156103b6576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015161ffff9081169184019190915260408086018051831660c08087019182526060808a01518716948801949094526080808a01805188169589019590955290890180519188019190915260e0808a015160a0890152925190941690526101008088015165ffffffffffff169186019190915291519184019190915280518216610140840152511661052a578260c00151341015610509576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08301516105189034614f63565b610180820152306101208201526106bd565b336101208201523461018082015260006105476020840184614f76565b905011156106bd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff1681525085806020019061066b9190614f76565b6040518563ffffffff1660e01b815260040161068a9493929190614fe2565b600060405180830381600087803b1580156106a457600080fd5b505af11580156106b8573d6000803e3d6000fd5b505050505b60006106e2846101200151604080518082019091528181528151909101602082015290565b90506106ee8183610a5a565b61010081015161014082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610755576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107678660e001518760400151610c37565b8210156107a0576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361016001516001036107b557505050505050565b6107d686600001518760a00151886020015161ffff168960e0015186610c65565b915081600003610812576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661087d57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610877573d6000803e3d6000fd5b506108a4565b60608601516108a49073ffffffffffffffffffffffffffffffffffffffff83169084610981565b610180840151156108e257610180840151604051339180156108fc02916000818181858888f193505050501580156108e0573d6000803e3d6000fd5b505b8560a0015173ffffffffffffffffffffffffffffffffffffffff16866080015173ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c0015186604051610971929190918252602082015260400190565b60405180910390a4505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610d1e565b505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526000610ad58480516001018051915290565b60ff16905060005b81811015610c2b576000610af78680516001018051915290565b60ff16905060018103610b1457610b0d85610e2d565b9450610c18565b60028103610b2557610b0d85610ff5565b60038103610b3757610b0d8686611254565b60048103610b4957610b0d8686611832565b60058103610b5b57610b0d8686611bb9565b60068103610b6d57610b0d8686612367565b60078103610b7f57610b0d8686612891565b60088103610b9157610b0d8686612dcf565b60098103610be657610ba4600184614f63565b8214610bdc576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d8686613205565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5080610c23816150a4565b915050610add565b50829150505b92915050565b6000612710610c4683826150dc565b610c549061ffff16856150f7565b610c5e919061513d565b9392505050565b60006107d0841115610cac576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610cbe575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610cf45760646032840204610cf7565b60005b9050808303838214610d0f57610d0f8a8a84846139d7565b50505090910395945050505050565b6000610d80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613a9f9092919063ffffffff16565b9050805160001480610da1575080806020019051810190610da19190615178565b610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ca3565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408082018390526101608201839052610180820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610f0a576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014610f5e576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50959695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146110db576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff8116301480159061110957306101208601525b600061014086015280156111bc57600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505050505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916112199160040190815260200190565b600060405180830381600087803b15801561123357600080fd5b505af1158015611247573d6000803e3d6000fd5b5096979650505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff1661130f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff90911603611404576113ff816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b6114e0565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156114c057600080fd5b505af11580156114d4573d6000803e3d6000fd5b50503061012086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161158657905b606083015161010086015161ffff61271092830316918402908202908101908302816115b4576115b461510e565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e9190615208565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161168457876101000151611687565b60005b866040015161169757600061169e565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561170857600080fd5b505af115801561171c573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b49190615208565b9050818110806117d257506101008701516117cf9083615221565b81105b15611809576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915260006118ad8480516001018051915290565b60ff16905060008361010001519050600060028310156118f9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611b84576000611914600188614f63565b82106119205785611951565b6127106119338b80516002018051915290565b61ffff168a610100015161194791906150f7565b611951919061513d565b90508581111561198d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119978187614f63565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261012080820183815261014080840185815261016085018690526101808501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d015116909152909650611a368b82610a5a565b9050806101600151600103611a77576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611a945780610120015193508061014001519450611b68565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614611afe576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614611b68576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100810151611b789087615221565b955050506001016118ff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152611c4660405180606001604052806060815260200160608152602001606081525090565b6000611c588580516001018051915290565b60ff169050611c68816001615221565b67ffffffffffffffff811115611c8057611c806148ad565b604051908082528060200260200182016040528015611ca9578160200160208202803683370190505b508083526101408501518151909190600090611cc757611cc7615234565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b81811015611d6057855160140180519087528351611d23836001615221565b81518110611d3357611d33615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611d04565b50611d6b8582613ab6565b6020830152611d7a8582613b58565b6040830152815180516000919083908110611d9757611d97615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e319190615208565b90506000611e52846040015187610100015186600001518760200151613be1565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff1603611ee457611edf8460200151600081518110611ea657611ea6615234565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b611fe3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c78516929190600090611f4357611f43615234565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b8152600401611fa9949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015611fc357600080fd5b505af1158015611fd7573d6000803e3d6000fd5b50503061012089015250505b60005b838110156121e7576000611ffb826001615221565b905060008660000151828151811061201557612015615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168760000151848151811061204957612049615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612073576000612076565b60015b90506000600288600001515161208c9190614f63565b841061209857306120b7565b876020015183815181106120ae576120ae615234565b60200260200101515b9050876020015184815181106120cf576120cf615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836121165786858151811061210957612109615234565b6020026020010151612119565b60005b84612125576000612140565b87868151811061213757612137615234565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156121c057600080fd5b505af11580156121d4573d6000803e3d6000fd5b505060019095019450611fe69350505050565b5060008460000151848151811061220057612200615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229a9190615208565b905081600183516122ab9190614f63565b815181106122bb576122bb615234565b602002602001015187610100018181525050828110806122e957506101008701516122e69084615221565b81105b15612320576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845180518590811061233457612334615234565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff90811660208301526101408401511661247a576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156124e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250c9190615208565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff161090506125a86040518060600160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff16815250613e16565b801561268c5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561264f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126739190615263565b9150508061268090615287565b61010087015250612774565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561273c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127609190615263565b50905061276c81615287565b610100870152505b61277c613f7f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e9190615208565b90508281108061282c57506101008601516128299084615221565b81105b15612863576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261291e60405180606001604052806060815260200160608152602001606081525090565b60006129308580516001018051915290565b60ff16905061293f8582613ab6565b825261294b8582613ab6565b60208301528151600090612960600184614f63565b8151811061297057612970615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156129eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0f9190615208565b905060005b83811015612cd75760008115612a4e578551612a31600184614f63565b81518110612a4157612a41615234565b6020026020010151612a55565b8761014001515b905085600001518281518110612a6d57612a6d615234565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516060810182526101008d015181526101208d01518416948101949094529184169183018290521190612ace90613e16565b82600003612ade57306101208a01525b600087602001518481518110612af657612af6615234565b602002602001015190508115612be0576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc79190615263565b91505080612bd490615287565b6101008c015250612cc4565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb09190615263565b509050612cbc81615287565b6101008c0152505b612ccc613f7f565b505050600101612a14565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6e9190615208565b905081811080612d8c5750610100870151612d899083615221565b81105b15612dc3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff9283161592918216159130911614613006577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612fe657600080fd5b505af1158015612ffa573d6000803e3d6000fd5b50503061012088015250505b6000816130a35783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561307a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309e9190615208565b6130a5565b475b9050826130e5576130e5846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff16613fdf9092919063ffffffff16565b61312a84608001518560a0015186602001518661310357600061310a565b8961010001515b886040015189606001518c610100015160008b8061312557508a5b6140d5565b6000826131c75784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561319e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c29190615208565b6131c9565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506131f38282614f63565b61010088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526132a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613431576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff166101008201528451602080820180519092010186526101208201526040516133fc9082906020016152bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613543578060800151516000036134a5578251610140840151602085015161010086015161349e93929161ffff169080610c65565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3866080015187610100015160405161353a929190918252602082015260400190565b60405180910390a45b6135558360a001518460c00151610c37565b8361010001511015613593576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff91821691161561377f5761012084015173ffffffffffffffffffffffffffffffffffffffff1630146136d1577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156136b157600080fd5b505af11580156136c5573d6000803e3d6000fd5b50503061012087015250505b61377f8260800151516000146136e75781613756565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613732573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061375691906152d2565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff169190613fdf565b6001610160850152608082015151156137985780613807565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380791906152d2565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff16146138665785610180015161387c565b85610180015186610100015161387c9190615221565b8451602086015160408701516101008a015160c08b01513091906138a1908290610c37565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c6080015151116138e7578d604001516138e9565b305b604051602001613924919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b16835261399499989796959493926004016152ef565b6000604051808303818588803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b5050600061018088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060613aae84846000856145d1565b949350505050565b60608167ffffffffffffffff811115613ad157613ad16148ad565b604051908082528060200260200182016040528015613afa578160200160208202803683370190505b50905060005b82811015613b515783516014018051908552828281518110613b2457613b24615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613b00565b5092915050565b60608167ffffffffffffffff811115613b7357613b736148ad565b604051908082528060200260200182016040528015613b9c578160200160208202803683370190505b50905060005b82811015613b515783516002018051908552828281518110613bc657613bc6615234565b61ffff90921660209283029190910190910152600101613ba2565b805182516060919067ffffffffffffffff811115613c0157613c016148ad565b604051908082528060200260200182016040528015613c2a578160200160208202803683370190505b5091508482600081518110613c4157613c41615234565b60200260200101818152505060005b81811015613e0c576000858281518110613c6c57613c6c615234565b60200260200101519050600086836001613c869190615221565b81518110613c9657613c96615234565b602002602001015190506000898481518110613cb457613cb4615234565b6020026020010151612710613cc991906150dc565b61ffff169050600080888681518110613ce457613ce4615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d5a91906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115613db557905b828b0282612710020181848d020281613dd057613dd061510e565b049a508a88613de0886001615221565b81518110613df057613df0615234565b6020908102919091010152505060019093019250613c50915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613e74576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613fdd576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261406b84826146ea565b6140cf5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526140c59085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109d3565b6140cf8482610d1e565b50505050565b8860ff1660010361420357871561418e576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561417057600080fd5b505af1158015614184573d6000803e3d6000fd5b50505050506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614157565b8860ff166002036143435787156142ce576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156142a3573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906142c89190615208565b506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614285565b8860ff166003036144e45787156143c1576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614285565b801561443b576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614285565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af11580156144c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c89190615208565b8860ff16600403614594578715614527576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614157565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b606082471015614663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ca3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161468c919061539b565b60006040518083038185875af1925050503d80600081146146c9576040519150601f19603f3d011682016040523d82523d6000602084013e6146ce565b606091505b50915091506146df878383876147ab565b979650505050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614714919061539b565b6000604051808303816000865af19150503d8060008114614751576040519150601f19603f3d011682016040523d82523d6000602084013e614756565b606091505b50915091508180156147805750805115806147805750808060200190518101906147809190615178565b80156147a2575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060831561484157825160000361483a5773ffffffffffffffffffffffffffffffffffffffff85163b61483a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca3565b5081613aae565b613aae83838151156148565781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca391906153b7565b61ffff8116811461489a57600080fd5b50565b80356148a88161488a565b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614900576149006148ad565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561494d5761494d6148ad565b604052919050565b600067ffffffffffffffff82111561496f5761496f6148ad565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149ac57600080fd5b81356149bf6149ba82614955565b614906565b8181528460208386010111156149d457600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461489a57600080fd5b80356148a8816149f1565b60008060008060008060c08789031215614a3757600080fd5b8635614a428161488a565b9550602087013567ffffffffffffffff80821115614a5f57600080fd5b614a6b8a838b0161499b565b96506040890135955060608901359150614a84826149f1565b9093506080880135925060a08801359080821115614aa157600080fd5b50614aae89828a0161499b565b9150509295509295509295565b65ffffffffffff8116811461489a57600080fd5b80356148a881614abb565b600060408284031215614aec57600080fd5b50919050565b60008060408385031215614b0557600080fd5b823567ffffffffffffffff80821115614b1d57600080fd5b908401906101408287031215614b3257600080fd5b614b3a6148dc565b614b4383614a13565b8152614b516020840161489d565b6020820152614b626040840161489d565b6040820152614b7360608401614a13565b6060820152614b8460808401614a13565b6080820152614b9560a08401614a13565b60a082015260c083013560c082015260e083013560e0820152610100614bbc818501614acf565b908201526101208381013583811115614bd457600080fd5b614be08982870161499b565b828401525050809450506020850135915080821115614bfe57600080fd5b50614c0b85828601614ada565b9150509250929050565b80516148a8816149f1565b80516148a88161488a565b80516148a881614abb565b60005b83811015614c51578181015183820152602001614c39565b50506000910152565b600082601f830112614c6b57600080fd5b8151614c796149ba82614955565b818152846020838601011115614c8e57600080fd5b613aae826020830160208701614c36565b600060208284031215614cb157600080fd5b815167ffffffffffffffff80821115614cc957600080fd5b908301906101408286031215614cde57600080fd5b614ce66148dc565b614cef83614c15565b8152614cfd60208401614c20565b6020820152614d0e60408401614c20565b6040820152614d1f60608401614c15565b6060820152614d3060808401614c15565b6080820152614d4160a08401614c15565b60a082015260c083015160c082015260e083015160e0820152610100614d68818501614c2b565b908201526101208381015183811115614d8057600080fd5b614d8c88828701614c5a565b918301919091525095945050505050565b60008151808452614db5816020860160208601614c36565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006101406020830151614e1b602086018261ffff169052565b506040830151614e31604086018261ffff169052565b506060830151614e59606086018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151614e81608086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614ea960a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015160c085015260e083015160e085015261010080840151614ed88287018265ffffffffffff169052565b5050610120808401518282870152614ef283870182614d9d565b9695505050505050565b604081526000614f0f6040830185614de7565b828103602084015283518152602084015160406020830152614ef26040830182614d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c3157610c31614f34565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614fab57600080fd5b83018035915067ffffffffffffffff821115614fc657600080fd5b602001915036819003821315614fdb57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150d5576150d5614f34565b5060010190565b61ffff828116828216039080821115613b5157613b51614f34565b8082028115828204841417610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615173577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561518a57600080fd5b81518015158114610c5e57600080fd5b80516dffffffffffffffffffffffffffff811681146148a857600080fd5b6000806000606084860312156151cd57600080fd5b6151d68461519a565b92506151e46020850161519a565b9150604084015163ffffffff811681146151fd57600080fd5b809150509250925092565b60006020828403121561521a57600080fd5b5051919050565b80820180821115610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561527657600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036152b8576152b8614f34565b5060000390565b602081526000610c5e6020830184614de7565b6000602082840312156152e457600080fd5b8151610c5e816149f1565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615362610180840182614d9d565b905082810360e08401526153768186614d9d565b905082810361010084015261538b8185614d9d565b9c9b505050505050505050505050565b600082516153ad818460208701614c36565b9190910192915050565b602081526000610c5e6020830184614d9d56fea26469706673582212204eecdc76d361ea4a608ec1291a66f39b61f591d844e03c8f4164adb5e8c419c464736f6c63430008130033", + "numDeployments": 7, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"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\":\"InvalidSgReceiveSrcAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSgReceiverSender\",\"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\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"bytes\",\"name\":\"_srcAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountLD\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sgReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"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\":\"warpLinkEngagePermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{\"sgReceive(uint16,bytes,uint256,address,uint256,bytes)\":{\"notice\":\"Cross-chain callback from Stargate The tokens have already been received by this contract, `t.payer` is set to this contract before `sgReceive` is called by the router. The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the same message more than once. The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the Stargate composer be compromised, an attacker can drain this contract. If the payload can not be decoded, tokens are left in this contract. If execution runs out of gas, tokens are left in this contract. If an error occurs during engage, such as insufficient output amount, tokens are refunded to the recipient. See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\"}},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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';\\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\\n bytes payload;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n address paramTokenIn;\\n uint256 paramAmountIn;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint48 paramDeadline;\\n uint256 amount;\\n address payer;\\n address token;\\n /**\\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\\n */\\n uint256 usePermit;\\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 if (t.usePermit == 1) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\\n }\\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 if (t.usePermit == 1) {\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\\n }\\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 if (t.usePermit == 1) {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(\\n t.payer,\\n params.pools[0],\\n (uint160)(t.amount),\\n t.token\\n );\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\\n }\\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({\\n payer: t.payer,\\n token: t.token,\\n amount: t.amount,\\n usePermit: t.usePermit\\n })\\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({\\n payer: t.payer,\\n token: tokenIn,\\n amount: t.amount,\\n usePermit: t.usePermit\\n })\\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 if (t.usePermit == 1) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\\n }\\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 useEth: isFromEth || isToEth,\\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 * Cross-chain callback from Stargate\\n *\\n * The tokens have already been received by this contract, `t.payer` is set to this contract\\n * before `sgReceive` is called by the router.\\n *\\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\\n * same message more than once.\\n *\\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\\n * Stargate composer be compromised, an attacker can drain this contract.\\n *\\n * If the payload can not be decoded, tokens are left in this contract.\\n * If execution runs out of gas, tokens are left in this contract.\\n *\\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\\n * to the recipient.\\n *\\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\\n */\\n function sgReceive(\\n uint16, // _srcChainId\\n bytes memory _srcAddress,\\n uint256, // _nonce\\n address _token,\\n uint256 amountLD,\\n bytes memory payload\\n ) external {\\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\\n revert InvalidSgReceiverSender();\\n }\\n\\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\\n // From https://ethereum.stackexchange.com/a/50528\\n address srcAddress;\\n\\n assembly {\\n srcAddress := mload(add(_srcAddress, 20))\\n }\\n\\n if (srcAddress != address(this)) {\\n // NOTE: This assumes that this contract is deployed at the same address on every chain\\n revert InvalidSgReceiveSrcAddress();\\n }\\n\\n Params memory params = abi.decode(payload, (Params));\\n\\n if (params.tokenIn == address(0)) {\\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\\n // otherwise because `_token` may be different on this chain\\n _token = address(0);\\n }\\n\\n try\\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\\n Params({\\n partner: params.partner,\\n feeBps: params.feeBps,\\n slippageBps: params.slippageBps,\\n recipient: params.recipient,\\n tokenIn: _token,\\n tokenOut: params.tokenOut,\\n amountIn: amountLD,\\n amountOut: params.amountOut,\\n deadline: params.deadline,\\n commands: params.commands\\n })\\n )\\n {} catch {\\n // Refund tokens to the recipient\\n if (_token == address(0)) {\\n payable(params.recipient).transfer(amountLD);\\n } else {\\n IERC20(_token).safeTransfer(params.recipient, amountLD);\\n }\\n }\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\\n * in this function.\\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 * - dstGasForCall (uint32)\\n * - tokenOut (address) when `dstGasForCall` > 0\\n * - amountOut (uint256) when `dstGasForCall` > 0\\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n params.dstGasForCall = stream.readUint32();\\n\\n if (params.dstGasForCall > 0) {\\n // NOTE: `amountIn` is left as zero\\n Params memory destParams;\\n destParams.partner = t.paramPartner;\\n destParams.feeBps = t.paramFeeBps;\\n destParams.slippageBps = t.paramSlippageBps;\\n destParams.recipient = t.paramRecipient;\\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\\n // the same address as on this chain\\n destParams.tokenIn = t.token;\\n destParams.tokenOut = stream.readAddress();\\n destParams.amountOut = stream.readUint256();\\n destParams.deadline = t.paramDeadline;\\n destParams.commands = stream.readBytes();\\n params.payload = abi.encode(destParams);\\n }\\n\\n if (t.token != t.paramTokenIn) {\\n if (params.payload.length == 0) {\\n // If the tokens are being delivered directly to the recipient without a second\\n // WarpLink engage, the fee is charged on this chain\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibStarVault.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n }\\n\\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\\n\\n if (t.token != address(0)) {\\n if (t.payer != address(this)) {\\n if (t.usePermit == 1) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n t.payer,\\n address(this),\\n (uint160)(t.amount),\\n t.token\\n );\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\\n }\\n\\n // Update the payer to this contract\\n // TODO: Is this value ever read?\\n t.payer = address(this);\\n }\\n\\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\\n IERC20(t.token).forceApprove(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\\n t.amount\\n );\\n }\\n\\n t.jumped = 1;\\n\\n // Swap on the composer if there is a payload, else the router\\n IStargateRouter(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\\n ).swap{\\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\\n }({\\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\\n // more on the other chain. It also assumes the tokens are of nearly equal value\\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: params.dstGasForCall,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n // NOTE: This assumes the contract is deployed at the same address on every chain.\\n // If this is not the case, a new param needs to be added with the next WarpLink address\\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\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\\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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function warpLinkEngagePermit(\\n Params calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n TransientState memory t;\\n t.paramPartner = params.partner;\\n t.paramFeeBps = params.feeBps;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.usePermit = 1;\\n\\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 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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0xafd9df86ea5bc03ea83d33890bbbe7e383f84bec96e5b67dd99e7d717bc9bcb3\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\\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 error InvalidSgReceiverSender();\\n error InvalidSgReceiveSrcAddress();\\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 calldata params) external payable;\\n\\n function warpLinkEngagePermit(\\n Params calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n}\\n\",\"keccak256\":\"0x0eff4788d9f45d72b6a05f34f1e8236a6f9d76a4778396d9a53c66ec04ebf726\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IStargateReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\n\\ninterface IStargateReceiver {\\n function sgReceive(\\n uint16 _srcChainId, // the remote chainId sending the tokens\\n bytes memory _srcAddress, // the remote Bridge address\\n uint256 _nonce,\\n address _token, // the token contract on the local chain\\n uint256 amountLD, // the qty of local _token contract tokens\\n bytes memory payload\\n ) external;\\n}\\n\",\"keccak256\":\"0x7fd06c09139156a4f09a77eac28e453a1d2041a8cf01a108fc875c65192cb637\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50615c3880620000216000396000f3fe6080604052600436106100345760003560e01c8063a703fc4014610039578063ab8236f31461004e578063dcc455511461006e575b600080fd5b61004c610047366004615184565b610081565b005b34801561005a57600080fd5b5061004c610069366004615368565b6106c6565b61004c61007c366004615405565b6109ac565b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152906100fd9084018461543a565b73ffffffffffffffffffffffffffffffffffffffff1681526101256040840160208501615457565b61ffff16602082015261013e6060840160408501615457565b61ffff1660c0820152610157608084016060850161543a565b73ffffffffffffffffffffffffffffffffffffffff16604082015261018260a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0840135608083015260e084013560a08301526101c490840160408501615457565b61ffff1660c08201526101df61012084016101008501615488565b65ffffffffffff1660e082015260c083013561010082015261020760a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff9081166101408301526001610160830152336101208301819052346101a08401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e08101909152921691632b67b570919080606081018061028a60a08b0160808c0161543a565b73ffffffffffffffffffffffffffffffffffffffff908116825260c08b01351660208201526040016102c46101208b016101008c01615488565b65ffffffffffff908116825289351660209182015290825230908201526040016102f661012089016101008a01615488565b65ffffffffffff16905261030d60208701876154a5565b6040518563ffffffff1660e01b815260040161032c9493929190615511565b600060405180830381600087803b15801561034657600080fd5b505af115801561035a573d6000803e3d6000fd5b5050505060006103ae8480610120019061037491906154a5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f4192505050565b90506103ba8183610f5b565b610100810151610140820151919350906103da60c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043e576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61045b60e08701356104566060890160408a01615457565b611140565b821015610494576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361018001516001036104a957505050505050565b6104e86104b9602088018861543a565b6104c960c0890160a08a0161543a565b6104d960408a0160208b01615457565b61ffff168960e001358661116e565b915081600003610524576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661059a5761054f608087016060880161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610594573d6000803e3d6000fd5b506105cb565b6105cb6105ad608088016060890161543a565b73ffffffffffffffffffffffffffffffffffffffff83169084611227565b6101a084015115610609576101a0840151604051339180156108fc02916000818181858888f19350505050158015610607573d6000803e3d6000fd5b505b61061960c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff1661063f60a088016080890161543a565b73ffffffffffffffffffffffffffffffffffffffff16610662602089018961543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c00135866040516106b6929190918252602082015260400190565b60405180910390a4505050505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461078d576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906107a39190615662565b608081015190915073ffffffffffffffffffffffffffffffffffffffff166107ca57600094505b3063dcc4555173ffffffffffffffffffffffffffffffffffffffff8716156107f35760006107f5565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff1681526020018561012001518152506040518363ffffffff1660e01b81526004016108e191906157aa565b6000604051808303818588803b1580156108fa57600080fd5b505af19350505050801561090c575060015b6109a25773ffffffffffffffffffffffffffffffffffffffff851661097b57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610975573d6000803e3d6000fd5b506109a2565b60608101516109a29073ffffffffffffffffffffffffffffffffffffffff87169086611227565b5050505050505050565b6109be61012082016101008301615488565b65ffffffffffff164211156109ff576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082015290610a7b9083018361543a565b73ffffffffffffffffffffffffffffffffffffffff168152610aa36040830160208401615457565b61ffff166020820152610abc6060830160408401615457565b61ffff1660c0820152610ad5608083016060840161543a565b73ffffffffffffffffffffffffffffffffffffffff166040820152610b0060a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0830135608083015260e083013560a0830152610b4290830160408401615457565b61ffff1660c0820152610b5d61012083016101008401615488565b65ffffffffffff1660e082015260c0820135610100820152610b8560a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff166101408201526000610bb360a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1603610c2c578160c00135341015610c0c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c1a60c0830135346158dc565b6101a082015230610120820152610c3b565b33610120820152346101a08201525b6000610c4e6103746101208501856154a5565b9050610c5a8183610f5b565b61010081015161014082015191935090610c7a60c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cde576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cf660e08601356104566060880160408901615457565b821015610d2f576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836101800151600103610d43575050505050565b610d82610d53602087018761543a565b610d6360c0880160a0890161543a565b610d736040890160208a01615457565b61ffff168860e001358661116e565b915081600003610dbe576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e3457610de9608086016060870161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610e2e573d6000803e3d6000fd5b50610e47565b610e476105ad608087016060880161543a565b6101a084015115610e85576101a0840151604051339180156108fc02916000818181858888f19350505050158015610e83573d6000803e3d6000fd5b505b610e9560c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ebb60a087016080880161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ede602088018861543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38860c0013586604051610f32929190918252602082015260400190565b60405180910390a45050505050565b604080518082019091528181528151909101602082015290565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000610fde8480516001018051915290565b60ff16905060005b818110156111345760006110008680516001018051915290565b60ff1690506001810361101d5761101685611300565b9450611121565b6002810361102e57611016856114d0565b600381036110405761101686866117f2565b60048103611052576110168686611e2a565b600581036110645761101686866121c1565b600681036110765761101686866129e3565b60078103611088576110168686612f20565b6008810361109a576110168686613471565b600981036110ef576110ad6001846158dc565b82146110e5576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61101686866138fd565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061112c816158ef565b915050610fe6565b50829150505b92915050565b600061271061114f8382615927565b61115d9061ffff1685615942565b6111679190615988565b9392505050565b60006107d08411156111b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156111c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156111fd5760646032840204611200565b60005b9050808303838214611218576112188a8a8484614125565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112fb9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526141ed565b505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140808201839052610160820183905261018082018390526101a0820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff16156113e5576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014611439576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b1580156114b057600080fd5b505af11580156114c4573d6000803e3d6000fd5b50959695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146115be576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff811630148015906115ec57306101208601525b6000610140860152801561175a578461016001516001036116b057600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b5050505061175a565b82546101008601516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015611734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175891906159c3565b505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916117b79160040190815260200190565b600060405180830381600087803b1580156117d157600080fd5b505af11580156117e5573d6000803e3d6000fd5b5096979650505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff166118b5576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff909116036119aa576119a5816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b611ad8565b826101600151600103611a90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015611a7357600080fd5b505af1158015611a87573d6000803e3d6000fd5b50505050611ad0565b611ad0836101200151826020015185610100015186610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208401525b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151611b7e57905b606083015161010086015161ffff6127109283031691840290820290810190830281611bac57611bac615959565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c469190615a53565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8560400151611c7c57876101000151611c7f565b60005b8660400151611c8f576000611c96565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015611d0057600080fd5b505af1158015611d14573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190615a53565b905081811080611dca5750610100870151611dc79083615a6c565b81105b15611e01576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000611ead8480516001018051915290565b60ff1690506000836101000151905060006002831015611ef9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561218c576000611f146001886158dc565b8210611f205785611f51565b612710611f338b80516002018051915290565b61ffff168a6101000151611f479190615942565b611f519190615988565b905085811115611f8d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f9781876158dc565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610120808201838152610140808401858152610160850186905261018085018690526101a08501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d01511690915290965061203e8b82610f5b565b905080610180015160010361207f576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361209c5780610120015193508061014001519450612170565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614612106576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614612170576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008101516121809087615a6c565b95505050600101611eff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261225660405180606001604052806060815260200160608152602001606081525090565b60006122688580516001018051915290565b60ff169050612278816001615a6c565b67ffffffffffffffff81111561229057612290615202565b6040519080825280602002602001820160405280156122b9578160200160208202803683370190505b5080835261014085015181519091906000906122d7576122d7615a7f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561237057855160140180519087528351612333836001615a6c565b8151811061234357612343615a7f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612314565b5061237b8582614360565b602083015261238a8582614402565b60408301528151805160009190839081106123a7576123a7615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615a53565b9050600061246284604001518761010001518660000151876020015161448b565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff16036124f4576124ef84602001516000815181106124b6576124b6615a7f565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b61265f565b8561016001516001036125fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061256057612560615a7f565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b81526004016125c6949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b50505050612657565b612657866101200151856020015160008151811061261d5761261d615a7f565b602002602001015188610100015189610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208701525b60005b83811015612863576000612677826001615a6c565b905060008660000151828151811061269157612691615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16876000015184815181106126c5576126c5615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106126ef5760006126f2565b60015b90506000600288600001515161270891906158dc565b84106127145730612733565b8760200151838151811061272a5761272a615a7f565b60200260200101515b90508760200151848151811061274b5761274b615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836127925786858151811061278557612785615a7f565b6020026020010151612795565b60005b846127a15760006127bc565b8786815181106127b3576127b3615a7f565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561283c57600080fd5b505af1158015612850573d6000803e3d6000fd5b5050600190950194506126629350505050565b5060008460000151848151811061287c5761287c615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129169190615a53565b9050816001835161292791906158dc565b8151811061293757612937615a7f565b6020026020010151876101000181815250508281108061296557506101008701516129629084615a6c565b81105b1561299c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518051859081106129b0576129b0615a7f565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015261014084015116612afe576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190615a53565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff16109050612c376040518060800160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018761016001518152506146c0565b8015612d1b5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d029190615aae565b91505080612d0f90615ad2565b61010087015250612e03565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def9190615aae565b509050612dfb81615ad2565b610100870152505b612e0b61484f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615a53565b905082811080612ebb5750610100860151612eb89084615a6c565b81105b15612ef2576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a0810191909152612fb560405180606001604052806060815260200160608152602001606081525090565b6000612fc78580516001018051915290565b60ff169050612fd68582614360565b8252612fe28582614360565b60208301528151600090612ff76001846158dc565b8151811061300757613007615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190615a53565b905060005b8381101561337957600081156130e55785516130c86001846158dc565b815181106130d8576130d8615a7f565b60200260200101516130ec565b8761014001515b90508560000151828151811061310457613104615a7f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516080810182526101008d015181526101208d01518416948101949094529184169183018290526101608b015160608401521190613170906146c0565b8260000361318057306101208a01525b60008760200151848151811061319857613198615a7f565b602002602001015190508115613282576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615aae565b9150508061327690615ad2565b6101008c015250613366565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561332e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133529190615aae565b50905061335e81615ad2565b6101008c0152505b61336e61484f565b5050506001016130ab565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156133ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134109190615a53565b90508181108061342e575061010087015161342b9083615a6c565b81105b15613465576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146136fe578461016001516001036136ba577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561369d57600080fd5b505af11580156136b1573d6000803e3d6000fd5b505050506136f6565b6136f68561012001513087610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208601525b60008161379b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137969190615a53565b61379d565b475b9050826137dd576137dd846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166148af9092919063ffffffff16565b61382284608001518560a001518660200151866137fb576000613802565b8961010001515b886040015189606001518c610100015160008b8061381d57508a5b61499f565b6000826138bf5784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ba9190615a53565b6138c1565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506138eb82826158dc565b61010088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526139a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613b31576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff16610100820152845160208082018051909201018652610120820152604051613afc9082906020016157aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613c4357806080015151600003613ba55782516101408401516020850151610100860151613b9e93929161ffff16908061116e565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38660800151876101000151604051613c3a929190918252602082015260400190565b60405180910390a45b613c558360a001518460c00151611140565b8361010001511015613c93576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff918216911615613ecd5761012084015173ffffffffffffffffffffffffffffffffffffffff163014613e1f57836101600151600103613ddb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015613dbe57600080fd5b505af1158015613dd2573d6000803e3d6000fd5b50505050613e17565b613e178461012001513086610100015187610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208501525b613ecd826080015151600014613e355781613ea4565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea49190615b0a565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff1691906148af565b600161018085015260808201515115613ee65780613f55565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f559190615b0a565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff1614613fb457856101a00151613fca565b856101a00151866101000151613fca9190615a6c565b8451602086015160408701516101008a015160c08b0151309190613fef908290611140565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c608001515111614035578d60400151614037565b305b604051602001614072919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b1683526140e29998979695949392600401615b27565b6000604051808303818588803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b505060006101a088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b600061424f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614e9b9092919063ffffffff16565b905080516000148061427057508080602001905181019061427091906159c3565b6112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016111ac565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261435a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611279565b50505050565b60608167ffffffffffffffff81111561437b5761437b615202565b6040519080825280602002602001820160405280156143a4578160200160208202803683370190505b50905060005b828110156143fb57835160140180519085528282815181106143ce576143ce615a7f565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016143aa565b5092915050565b60608167ffffffffffffffff81111561441d5761441d615202565b604051908082528060200260200182016040528015614446578160200160208202803683370190505b50905060005b828110156143fb578351600201805190855282828151811061447057614470615a7f565b61ffff9092166020928302919091019091015260010161444c565b805182516060919067ffffffffffffffff8111156144ab576144ab615202565b6040519080825280602002602001820160405280156144d4578160200160208202803683370190505b50915084826000815181106144eb576144eb615a7f565b60200260200101818152505060005b818110156146b657600085828151811061451657614516615a7f565b602002602001015190506000868360016145309190615a6c565b8151811061454057614540615a7f565b60200260200101519050600089848151811061455e5761455e615a7f565b60200260200101516127106145739190615927565b61ffff16905060008088868151811061458e5761458e615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156145e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146049190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561465f57905b828b0282612710020181848d02028161467a5761467a615959565b049a508a8861468a886001615a6c565b8151811061469a5761469a615a7f565b60209081029190910101525050600190930192506144fa915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361471e576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036148ad576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261493b8482614eb2565b61435a5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526149959085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611279565b61435a84826141ed565b8860ff16600103614acd578715614a58576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015614a3a57600080fd5b505af1158015614a4e573d6000803e3d6000fd5b5050505050614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614a21565b8860ff16600203614c0d578715614b98576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015614b6d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190614b929190615a53565b50614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614b4f565b8860ff16600303614dae578715614c8b576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614b4f565b8015614d05576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614b4f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015614d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b929190615a53565b8860ff16600403614e5e578715614df1576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614a21565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6060614eaa8484600085614f73565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614edc9190615bd3565b6000604051808303816000865af19150503d8060008114614f19576040519150601f19603f3d011682016040523d82523d6000602084013e614f1e565b606091505b5091509150818015614f48575080511580614f48575080806020019051810190614f4891906159c3565b8015614f6a575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b606082471015615005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016111ac565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161502e9190615bd3565b60006040518083038185875af1925050503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b50915091506150818783838761508c565b979650505050505050565b6060831561512257825160000361511b5773ffffffffffffffffffffffffffffffffffffffff85163b61511b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016111ac565b5081614eaa565b614eaa83838151156151375781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac9190615bef565b6000610140828403121561517e57600080fd5b50919050565b6000806040838503121561519757600080fd5b823567ffffffffffffffff808211156151af57600080fd5b6151bb8683870161516b565b935060208501359150808211156151d157600080fd5b508301604081860312156151e457600080fd5b809150509250929050565b61ffff811681146151ff57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561525557615255615202565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156152a2576152a2615202565b604052919050565b600067ffffffffffffffff8211156152c4576152c4615202565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261530157600080fd5b813561531461530f826152aa565b61525b565b81815284602083860101111561532957600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146151ff57600080fd5b60008060008060008060c0878903121561538157600080fd5b863561538c816151ef565b9550602087013567ffffffffffffffff808211156153a957600080fd5b6153b58a838b016152f0565b965060408901359550606089013591506153ce82615346565b9093506080880135925060a088013590808211156153eb57600080fd5b506153f889828a016152f0565b9150509295509295509295565b60006020828403121561541757600080fd5b813567ffffffffffffffff81111561542e57600080fd5b614eaa8482850161516b565b60006020828403121561544c57600080fd5b813561116781615346565b60006020828403121561546957600080fd5b8135611167816151ef565b65ffffffffffff811681146151ff57600080fd5b60006020828403121561549a57600080fd5b813561116781615474565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154da57600080fd5b83018035915067ffffffffffffffff8211156154f557600080fd5b60200191503681900382131561550a57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b80516155de81615346565b919050565b80516155de816151ef565b80516155de81615474565b60005b838110156156145781810151838201526020016155fc565b50506000910152565b600082601f83011261562e57600080fd5b815161563c61530f826152aa565b81815284602083860101111561565157600080fd5b614eaa8260208301602087016155f9565b60006020828403121561567457600080fd5b815167ffffffffffffffff8082111561568c57600080fd5b9083019061014082860312156156a157600080fd5b6156a9615231565b6156b2836155d3565b81526156c0602084016155e3565b60208201526156d1604084016155e3565b60408201526156e2606084016155d3565b60608201526156f3608084016155d3565b608082015261570460a084016155d3565b60a082015260c083015160c082015260e083015160e082015261010061572b8185016155ee565b90820152610120838101518381111561574357600080fd5b61574f8882870161561d565b918301919091525095945050505050565b600081518084526157788160208601602086016155f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526157d160208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516157e8604084018261ffff169052565b50604083015161ffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c083015160e083015260e08301516101008181850152808501519150506101206158938185018365ffffffffffff169052565b840151610140848101529050614eaa610160840182615760565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561113a5761113a6158ad565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615920576159206158ad565b5060010190565b61ffff8281168282160390808211156143fb576143fb6158ad565b808202811582820484141761113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156159d557600080fd5b8151801515811461116757600080fd5b80516dffffffffffffffffffffffffffff811681146155de57600080fd5b600080600060608486031215615a1857600080fd5b615a21846159e5565b9250615a2f602085016159e5565b9150604084015163ffffffff81168114615a4857600080fd5b809150509250925092565b600060208284031215615a6557600080fd5b5051919050565b8082018082111561113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215615ac157600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b0357615b036158ad565b5060000390565b600060208284031215615b1c57600080fd5b815161116781615346565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615b9a610180840182615760565b905082810360e0840152615bae8186615760565b9050828103610100840152615bc38185615760565b9c9b505050505050505050505050565b60008251615be58184602087016155f9565b9190910192915050565b602081526000611167602083018461576056fea26469706673582212202ce6a8f21a153c83c150806f9ce2e260656621d27c2de20b34fdaa1dbce5be3f64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c8063a703fc4014610039578063ab8236f31461004e578063dcc455511461006e575b600080fd5b61004c610047366004615184565b610081565b005b34801561005a57600080fd5b5061004c610069366004615368565b6106c6565b61004c61007c366004615405565b6109ac565b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152906100fd9084018461543a565b73ffffffffffffffffffffffffffffffffffffffff1681526101256040840160208501615457565b61ffff16602082015261013e6060840160408501615457565b61ffff1660c0820152610157608084016060850161543a565b73ffffffffffffffffffffffffffffffffffffffff16604082015261018260a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0840135608083015260e084013560a08301526101c490840160408501615457565b61ffff1660c08201526101df61012084016101008501615488565b65ffffffffffff1660e082015260c083013561010082015261020760a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff9081166101408301526001610160830152336101208301819052346101a08401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e08101909152921691632b67b570919080606081018061028a60a08b0160808c0161543a565b73ffffffffffffffffffffffffffffffffffffffff908116825260c08b01351660208201526040016102c46101208b016101008c01615488565b65ffffffffffff908116825289351660209182015290825230908201526040016102f661012089016101008a01615488565b65ffffffffffff16905261030d60208701876154a5565b6040518563ffffffff1660e01b815260040161032c9493929190615511565b600060405180830381600087803b15801561034657600080fd5b505af115801561035a573d6000803e3d6000fd5b5050505060006103ae8480610120019061037491906154a5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f4192505050565b90506103ba8183610f5b565b610100810151610140820151919350906103da60c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043e576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61045b60e08701356104566060890160408a01615457565b611140565b821015610494576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361018001516001036104a957505050505050565b6104e86104b9602088018861543a565b6104c960c0890160a08a0161543a565b6104d960408a0160208b01615457565b61ffff168960e001358661116e565b915081600003610524576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661059a5761054f608087016060880161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610594573d6000803e3d6000fd5b506105cb565b6105cb6105ad608088016060890161543a565b73ffffffffffffffffffffffffffffffffffffffff83169084611227565b6101a084015115610609576101a0840151604051339180156108fc02916000818181858888f19350505050158015610607573d6000803e3d6000fd5b505b61061960c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff1661063f60a088016080890161543a565b73ffffffffffffffffffffffffffffffffffffffff16610662602089018961543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c00135866040516106b6929190918252602082015260400190565b60405180910390a4505050505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461078d576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906107a39190615662565b608081015190915073ffffffffffffffffffffffffffffffffffffffff166107ca57600094505b3063dcc4555173ffffffffffffffffffffffffffffffffffffffff8716156107f35760006107f5565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff1681526020018561012001518152506040518363ffffffff1660e01b81526004016108e191906157aa565b6000604051808303818588803b1580156108fa57600080fd5b505af19350505050801561090c575060015b6109a25773ffffffffffffffffffffffffffffffffffffffff851661097b57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610975573d6000803e3d6000fd5b506109a2565b60608101516109a29073ffffffffffffffffffffffffffffffffffffffff87169086611227565b5050505050505050565b6109be61012082016101008301615488565b65ffffffffffff164211156109ff576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082015290610a7b9083018361543a565b73ffffffffffffffffffffffffffffffffffffffff168152610aa36040830160208401615457565b61ffff166020820152610abc6060830160408401615457565b61ffff1660c0820152610ad5608083016060840161543a565b73ffffffffffffffffffffffffffffffffffffffff166040820152610b0060a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0830135608083015260e083013560a0830152610b4290830160408401615457565b61ffff1660c0820152610b5d61012083016101008401615488565b65ffffffffffff1660e082015260c0820135610100820152610b8560a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff166101408201526000610bb360a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1603610c2c578160c00135341015610c0c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c1a60c0830135346158dc565b6101a082015230610120820152610c3b565b33610120820152346101a08201525b6000610c4e6103746101208501856154a5565b9050610c5a8183610f5b565b61010081015161014082015191935090610c7a60c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cde576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cf660e08601356104566060880160408901615457565b821015610d2f576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836101800151600103610d43575050505050565b610d82610d53602087018761543a565b610d6360c0880160a0890161543a565b610d736040890160208a01615457565b61ffff168860e001358661116e565b915081600003610dbe576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e3457610de9608086016060870161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610e2e573d6000803e3d6000fd5b50610e47565b610e476105ad608087016060880161543a565b6101a084015115610e85576101a0840151604051339180156108fc02916000818181858888f19350505050158015610e83573d6000803e3d6000fd5b505b610e9560c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ebb60a087016080880161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ede602088018861543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38860c0013586604051610f32929190918252602082015260400190565b60405180910390a45050505050565b604080518082019091528181528151909101602082015290565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000610fde8480516001018051915290565b60ff16905060005b818110156111345760006110008680516001018051915290565b60ff1690506001810361101d5761101685611300565b9450611121565b6002810361102e57611016856114d0565b600381036110405761101686866117f2565b60048103611052576110168686611e2a565b600581036110645761101686866121c1565b600681036110765761101686866129e3565b60078103611088576110168686612f20565b6008810361109a576110168686613471565b600981036110ef576110ad6001846158dc565b82146110e5576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61101686866138fd565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061112c816158ef565b915050610fe6565b50829150505b92915050565b600061271061114f8382615927565b61115d9061ffff1685615942565b6111679190615988565b9392505050565b60006107d08411156111b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156111c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156111fd5760646032840204611200565b60005b9050808303838214611218576112188a8a8484614125565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112fb9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526141ed565b505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140808201839052610160820183905261018082018390526101a0820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff16156113e5576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014611439576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b1580156114b057600080fd5b505af11580156114c4573d6000803e3d6000fd5b50959695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146115be576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff811630148015906115ec57306101208601525b6000610140860152801561175a578461016001516001036116b057600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b5050505061175a565b82546101008601516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015611734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175891906159c3565b505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916117b79160040190815260200190565b600060405180830381600087803b1580156117d157600080fd5b505af11580156117e5573d6000803e3d6000fd5b5096979650505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff166118b5576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff909116036119aa576119a5816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b611ad8565b826101600151600103611a90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015611a7357600080fd5b505af1158015611a87573d6000803e3d6000fd5b50505050611ad0565b611ad0836101200151826020015185610100015186610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208401525b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151611b7e57905b606083015161010086015161ffff6127109283031691840290820290810190830281611bac57611bac615959565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c469190615a53565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8560400151611c7c57876101000151611c7f565b60005b8660400151611c8f576000611c96565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015611d0057600080fd5b505af1158015611d14573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190615a53565b905081811080611dca5750610100870151611dc79083615a6c565b81105b15611e01576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000611ead8480516001018051915290565b60ff1690506000836101000151905060006002831015611ef9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561218c576000611f146001886158dc565b8210611f205785611f51565b612710611f338b80516002018051915290565b61ffff168a6101000151611f479190615942565b611f519190615988565b905085811115611f8d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f9781876158dc565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610120808201838152610140808401858152610160850186905261018085018690526101a08501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d01511690915290965061203e8b82610f5b565b905080610180015160010361207f576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361209c5780610120015193508061014001519450612170565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614612106576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614612170576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008101516121809087615a6c565b95505050600101611eff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261225660405180606001604052806060815260200160608152602001606081525090565b60006122688580516001018051915290565b60ff169050612278816001615a6c565b67ffffffffffffffff81111561229057612290615202565b6040519080825280602002602001820160405280156122b9578160200160208202803683370190505b5080835261014085015181519091906000906122d7576122d7615a7f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561237057855160140180519087528351612333836001615a6c565b8151811061234357612343615a7f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612314565b5061237b8582614360565b602083015261238a8582614402565b60408301528151805160009190839081106123a7576123a7615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615a53565b9050600061246284604001518761010001518660000151876020015161448b565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff16036124f4576124ef84602001516000815181106124b6576124b6615a7f565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b61265f565b8561016001516001036125fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061256057612560615a7f565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b81526004016125c6949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b50505050612657565b612657866101200151856020015160008151811061261d5761261d615a7f565b602002602001015188610100015189610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208701525b60005b83811015612863576000612677826001615a6c565b905060008660000151828151811061269157612691615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16876000015184815181106126c5576126c5615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106126ef5760006126f2565b60015b90506000600288600001515161270891906158dc565b84106127145730612733565b8760200151838151811061272a5761272a615a7f565b60200260200101515b90508760200151848151811061274b5761274b615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836127925786858151811061278557612785615a7f565b6020026020010151612795565b60005b846127a15760006127bc565b8786815181106127b3576127b3615a7f565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561283c57600080fd5b505af1158015612850573d6000803e3d6000fd5b5050600190950194506126629350505050565b5060008460000151848151811061287c5761287c615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129169190615a53565b9050816001835161292791906158dc565b8151811061293757612937615a7f565b6020026020010151876101000181815250508281108061296557506101008701516129629084615a6c565b81105b1561299c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518051859081106129b0576129b0615a7f565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015261014084015116612afe576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190615a53565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff16109050612c376040518060800160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018761016001518152506146c0565b8015612d1b5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d029190615aae565b91505080612d0f90615ad2565b61010087015250612e03565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def9190615aae565b509050612dfb81615ad2565b610100870152505b612e0b61484f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615a53565b905082811080612ebb5750610100860151612eb89084615a6c565b81105b15612ef2576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a0810191909152612fb560405180606001604052806060815260200160608152602001606081525090565b6000612fc78580516001018051915290565b60ff169050612fd68582614360565b8252612fe28582614360565b60208301528151600090612ff76001846158dc565b8151811061300757613007615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190615a53565b905060005b8381101561337957600081156130e55785516130c86001846158dc565b815181106130d8576130d8615a7f565b60200260200101516130ec565b8761014001515b90508560000151828151811061310457613104615a7f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516080810182526101008d015181526101208d01518416948101949094529184169183018290526101608b015160608401521190613170906146c0565b8260000361318057306101208a01525b60008760200151848151811061319857613198615a7f565b602002602001015190508115613282576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615aae565b9150508061327690615ad2565b6101008c015250613366565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561332e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133529190615aae565b50905061335e81615ad2565b6101008c0152505b61336e61484f565b5050506001016130ab565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156133ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134109190615a53565b90508181108061342e575061010087015161342b9083615a6c565b81105b15613465576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146136fe578461016001516001036136ba577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561369d57600080fd5b505af11580156136b1573d6000803e3d6000fd5b505050506136f6565b6136f68561012001513087610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208601525b60008161379b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137969190615a53565b61379d565b475b9050826137dd576137dd846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166148af9092919063ffffffff16565b61382284608001518560a001518660200151866137fb576000613802565b8961010001515b886040015189606001518c610100015160008b8061381d57508a5b61499f565b6000826138bf5784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ba9190615a53565b6138c1565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506138eb82826158dc565b61010088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526139a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613b31576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff16610100820152845160208082018051909201018652610120820152604051613afc9082906020016157aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613c4357806080015151600003613ba55782516101408401516020850151610100860151613b9e93929161ffff16908061116e565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38660800151876101000151604051613c3a929190918252602082015260400190565b60405180910390a45b613c558360a001518460c00151611140565b8361010001511015613c93576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff918216911615613ecd5761012084015173ffffffffffffffffffffffffffffffffffffffff163014613e1f57836101600151600103613ddb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015613dbe57600080fd5b505af1158015613dd2573d6000803e3d6000fd5b50505050613e17565b613e178461012001513086610100015187610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208501525b613ecd826080015151600014613e355781613ea4565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea49190615b0a565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff1691906148af565b600161018085015260808201515115613ee65780613f55565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f559190615b0a565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff1614613fb457856101a00151613fca565b856101a00151866101000151613fca9190615a6c565b8451602086015160408701516101008a015160c08b0151309190613fef908290611140565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c608001515111614035578d60400151614037565b305b604051602001614072919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b1683526140e29998979695949392600401615b27565b6000604051808303818588803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b505060006101a088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b600061424f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614e9b9092919063ffffffff16565b905080516000148061427057508080602001905181019061427091906159c3565b6112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016111ac565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261435a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611279565b50505050565b60608167ffffffffffffffff81111561437b5761437b615202565b6040519080825280602002602001820160405280156143a4578160200160208202803683370190505b50905060005b828110156143fb57835160140180519085528282815181106143ce576143ce615a7f565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016143aa565b5092915050565b60608167ffffffffffffffff81111561441d5761441d615202565b604051908082528060200260200182016040528015614446578160200160208202803683370190505b50905060005b828110156143fb578351600201805190855282828151811061447057614470615a7f565b61ffff9092166020928302919091019091015260010161444c565b805182516060919067ffffffffffffffff8111156144ab576144ab615202565b6040519080825280602002602001820160405280156144d4578160200160208202803683370190505b50915084826000815181106144eb576144eb615a7f565b60200260200101818152505060005b818110156146b657600085828151811061451657614516615a7f565b602002602001015190506000868360016145309190615a6c565b8151811061454057614540615a7f565b60200260200101519050600089848151811061455e5761455e615a7f565b60200260200101516127106145739190615927565b61ffff16905060008088868151811061458e5761458e615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156145e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146049190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561465f57905b828b0282612710020181848d02028161467a5761467a615959565b049a508a8861468a886001615a6c565b8151811061469a5761469a615a7f565b60209081029190910101525050600190930192506144fa915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361471e576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036148ad576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261493b8482614eb2565b61435a5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526149959085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611279565b61435a84826141ed565b8860ff16600103614acd578715614a58576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015614a3a57600080fd5b505af1158015614a4e573d6000803e3d6000fd5b5050505050614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614a21565b8860ff16600203614c0d578715614b98576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015614b6d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190614b929190615a53565b50614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614b4f565b8860ff16600303614dae578715614c8b576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614b4f565b8015614d05576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614b4f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015614d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b929190615a53565b8860ff16600403614e5e578715614df1576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614a21565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6060614eaa8484600085614f73565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614edc9190615bd3565b6000604051808303816000865af19150503d8060008114614f19576040519150601f19603f3d011682016040523d82523d6000602084013e614f1e565b606091505b5091509150818015614f48575080511580614f48575080806020019051810190614f4891906159c3565b8015614f6a575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b606082471015615005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016111ac565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161502e9190615bd3565b60006040518083038185875af1925050503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b50915091506150818783838761508c565b979650505050505050565b6060831561512257825160000361511b5773ffffffffffffffffffffffffffffffffffffffff85163b61511b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016111ac565b5081614eaa565b614eaa83838151156151375781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac9190615bef565b6000610140828403121561517e57600080fd5b50919050565b6000806040838503121561519757600080fd5b823567ffffffffffffffff808211156151af57600080fd5b6151bb8683870161516b565b935060208501359150808211156151d157600080fd5b508301604081860312156151e457600080fd5b809150509250929050565b61ffff811681146151ff57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561525557615255615202565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156152a2576152a2615202565b604052919050565b600067ffffffffffffffff8211156152c4576152c4615202565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261530157600080fd5b813561531461530f826152aa565b61525b565b81815284602083860101111561532957600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146151ff57600080fd5b60008060008060008060c0878903121561538157600080fd5b863561538c816151ef565b9550602087013567ffffffffffffffff808211156153a957600080fd5b6153b58a838b016152f0565b965060408901359550606089013591506153ce82615346565b9093506080880135925060a088013590808211156153eb57600080fd5b506153f889828a016152f0565b9150509295509295509295565b60006020828403121561541757600080fd5b813567ffffffffffffffff81111561542e57600080fd5b614eaa8482850161516b565b60006020828403121561544c57600080fd5b813561116781615346565b60006020828403121561546957600080fd5b8135611167816151ef565b65ffffffffffff811681146151ff57600080fd5b60006020828403121561549a57600080fd5b813561116781615474565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154da57600080fd5b83018035915067ffffffffffffffff8211156154f557600080fd5b60200191503681900382131561550a57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b80516155de81615346565b919050565b80516155de816151ef565b80516155de81615474565b60005b838110156156145781810151838201526020016155fc565b50506000910152565b600082601f83011261562e57600080fd5b815161563c61530f826152aa565b81815284602083860101111561565157600080fd5b614eaa8260208301602087016155f9565b60006020828403121561567457600080fd5b815167ffffffffffffffff8082111561568c57600080fd5b9083019061014082860312156156a157600080fd5b6156a9615231565b6156b2836155d3565b81526156c0602084016155e3565b60208201526156d1604084016155e3565b60408201526156e2606084016155d3565b60608201526156f3608084016155d3565b608082015261570460a084016155d3565b60a082015260c083015160c082015260e083015160e082015261010061572b8185016155ee565b90820152610120838101518381111561574357600080fd5b61574f8882870161561d565b918301919091525095945050505050565b600081518084526157788160208601602086016155f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526157d160208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516157e8604084018261ffff169052565b50604083015161ffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c083015160e083015260e08301516101008181850152808501519150506101206158938185018365ffffffffffff169052565b840151610140848101529050614eaa610160840182615760565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561113a5761113a6158ad565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615920576159206158ad565b5060010190565b61ffff8281168282160390808211156143fb576143fb6158ad565b808202811582820484141761113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156159d557600080fd5b8151801515811461116757600080fd5b80516dffffffffffffffffffffffffffff811681146155de57600080fd5b600080600060608486031215615a1857600080fd5b615a21846159e5565b9250615a2f602085016159e5565b9150604084015163ffffffff81168114615a4857600080fd5b809150509250925092565b600060208284031215615a6557600080fd5b5051919050565b8082018082111561113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215615ac157600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b0357615b036158ad565b5060000390565b600060208284031215615b1c57600080fd5b815161116781615346565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615b9a610180840182615760565b905082810360e0840152615bae8186615760565b9050828103610100840152615bc38185615760565b9c9b505050505050505050505050565b60008251615be58184602087016155f9565b9190910192915050565b602081526000611167602083018461576056fea26469706673582212202ce6a8f21a153c83c150806f9ce2e260656621d27c2de20b34fdaa1dbce5be3f64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/base/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json b/packages/hardhat/deployments/base/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json new file mode 100644 index 00000000..cf1aa121 --- /dev/null +++ b/packages/hardhat/deployments/base/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json @@ -0,0 +1,170 @@ +{ + "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" + }, + "@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * Perform the swap with tokens already moved to this contract\n */\n function curveExactInputSingleInternal(\n ExactInputSingleParams calldata params\n ) internal returns (uint256 amountOut) {\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 LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n useEth: params.tokenIn == address(0) || isToEth,\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function curveExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (params.tokenIn == address(0)) {\n revert PermitForEthToken();\n }\n\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 return curveExactInputSingleInternal(params);\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\n }\n\n return curveExactInputSingleInternal(params);\n }\n}\n" + }, + "contracts/facets/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract Stargate is IStargate {\n using SafeERC20 for IERC20;\n\n /**\n * Jump tokens with Stargate with input tokens already moved to this contract\n */\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.token,\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n // NOTE: This lookup is spending 319 gas\n IStargateRouter stargateRouter = IStargateRouter(\n LibWarp.state().stargateComposer.stargateRouter()\n );\n\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\n\n unchecked {\n stargateRouter.swap{value: msg.value}({\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\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\n }\n }\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable {\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.token,\n amount: 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 // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n uint160(params.amountIn),\n params.token\n );\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\n // Transfer tokens from the sender to this contract\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n address(0),\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n unchecked {\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\n _dstChainId: params.dstChainId,\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * NOTE: The tokens must already have been moved to the first pool\n */\n function uniswapV2LikeExactInputSingleInternal(\n ExactInputSingleParams memory params\n ) internal returns (uint256 amountOut) {\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : params.tokenIn,\n isToEth ? address(0) : params.tokenOut,\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\n }\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 the pool\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pool,\n (uint160)(params.amountIn),\n params.tokenIn\n );\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputInternal(\n ExactInputParams calldata params\n ) internal returns (uint256 amountOut) {\n LibWarp.State storage s = LibWarp.state();\n\n address[] memory tokens = params.tokens;\n uint256 poolLength = params.pools.length;\n bool isFromEth = tokens[0] == address(0);\n bool isToEth = tokens[poolLength] == address(0);\n\n if (isFromEth) {\n tokens[0] = address(s.weth);\n }\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : tokens[0],\n isToEth ? address(0) : tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\n } else {\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\n }\n\n return uniswapV2LikeExactInputInternal(params);\n }\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n // Permit tokens / set allowance\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n\n return uniswapV2LikeExactInputInternal(params);\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 {LibStarVault} from '../libraries/LibStarVault.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\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /**\n * NOTE: The tokens must already have been transferred to the pool\n */\n function uniswapV2ExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n address pair\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address tokenIn = params.tokenIn == address(0) ? address(s.weth) : params.tokenIn;\n address tokenOut = params.tokenOut == address(0) ? address(s.weth) : params.tokenOut;\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (tokenIn > 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 InsufficientOutputAmount();\n }\n\n bool zeroForOne = tokenIn < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.tokenOut == address(0)) {\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn == address(0) ? address(s.weth) : params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\n if (params.tokenIn == address(0)) {\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(address(s.weth)).safeTransfer(pair, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, pair, params.amountIn);\n }\n\n return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\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 return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n /**\n * NOTE: The tokens must already have been transferred to the first pool\n *\n * The path should be rewritten so address(0) is replaced by the WETH address\n */\n function uniswapV2ExactInputInternal(\n ExactInputParams calldata params,\n address[] memory path,\n address[] memory pairs,\n uint256[] memory amounts\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\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 = path[index] < path[indexPlusOne] ? true : false;\n address to = index < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH. 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(path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.path[0],\n params.path[pathLengthMinusOne],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[0] == address(0)) {\n // From ETH\n path[0] = address(s.weth);\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\n }\n\n if (params.path[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer WETH tokens to the first pool\n IERC20(path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n IERC20(path[0]).safeTransferFrom(msg.sender, pairs[0], params.amountIn);\n }\n\n return uniswapV2ExactInputInternal(params, path, pairs, amounts);\n }\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: 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 return uniswapV2ExactInputInternal(params, path, pairs, amounts);\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 if (callback.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n } else {\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\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 /**\n * NOTE: None of these arguments can be trusted\n */\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * KyperSwap V2 callback\n * NOTE: None of these arguments can be trusted\n */\n function swapCallback(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 {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n bool isFromEth = params.tokenIn == address(0);\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\n\n address tokenOut = params.tokenOut == address(0)\n ? address(LibWarp.state().weth)\n : params.tokenOut;\n\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\n\n bool zeroForOne = tokenIn < tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: tokenIn,\n amount: params.amountIn,\n usePermit: usePermit\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokenOut == address(0)) {\n // To ETH, unwrap WETH\n // TODO: This is read twice. Compare gas usage\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH, wrap it\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\n }\n\n function uniswapV3LikeExactInputInternal(\n ExactInputParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n uint256 poolLength = params.pools.length;\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\n address[] memory tokens = params.tokens;\n\n if (params.tokens[0] == address(0)) {\n tokens[0] = address(LibWarp.state().weth);\n }\n\n if (params.tokens[poolLength] == address(0)) {\n tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: payer,\n token: tokens[index],\n amount: amountOut,\n usePermit: usePermit\n })\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokens[poolLength] == address(0)) {\n // To ETH, unwrap\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.tokens[0],\n params.tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH, wrap it\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n }\n\n return uniswapV3LikeExactInputInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputInternal(params, 1);\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 {LibStarVault} from '../libraries/LibStarVault.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';\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\n bytes payload;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n address paramTokenIn;\n uint256 paramAmountIn;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint48 paramDeadline;\n uint256 amount;\n address payer;\n address token;\n /**\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\n */\n uint256 usePermit;\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 if (t.usePermit == 1) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\n }\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 if (t.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\n }\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(\n t.payer,\n params.pools[0],\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\n }\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({\n payer: t.payer,\n token: t.token,\n amount: t.amount,\n usePermit: t.usePermit\n })\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({\n payer: t.payer,\n token: tokenIn,\n amount: t.amount,\n usePermit: t.usePermit\n })\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\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 useEth: isFromEth || isToEth,\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 * Cross-chain callback from Stargate\n *\n * The tokens have already been received by this contract, `t.payer` is set to this contract\n * before `sgReceive` is called by the router.\n *\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\n * same message more than once.\n *\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\n * Stargate composer be compromised, an attacker can drain this contract.\n *\n * If the payload can not be decoded, tokens are left in this contract.\n * If execution runs out of gas, tokens are left in this contract.\n *\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\n * to the recipient.\n *\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\n */\n function sgReceive(\n uint16, // _srcChainId\n bytes memory _srcAddress,\n uint256, // _nonce\n address _token,\n uint256 amountLD,\n bytes memory payload\n ) external {\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\n revert InvalidSgReceiverSender();\n }\n\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\n // From https://ethereum.stackexchange.com/a/50528\n address srcAddress;\n\n assembly {\n srcAddress := mload(add(_srcAddress, 20))\n }\n\n if (srcAddress != address(this)) {\n // NOTE: This assumes that this contract is deployed at the same address on every chain\n revert InvalidSgReceiveSrcAddress();\n }\n\n Params memory params = abi.decode(payload, (Params));\n\n if (params.tokenIn == address(0)) {\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\n // otherwise because `_token` may be different on this chain\n _token = address(0);\n }\n\n try\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\n Params({\n partner: params.partner,\n feeBps: params.feeBps,\n slippageBps: params.slippageBps,\n recipient: params.recipient,\n tokenIn: _token,\n tokenOut: params.tokenOut,\n amountIn: amountLD,\n amountOut: params.amountOut,\n deadline: params.deadline,\n commands: params.commands\n })\n )\n {} catch {\n // Refund tokens to the recipient\n if (_token == address(0)) {\n payable(params.recipient).transfer(amountLD);\n } else {\n IERC20(_token).safeTransfer(params.recipient, amountLD);\n }\n }\n }\n\n /**\n * Jump to another chain using the Stargate bridge\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\n * in this function.\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 * - dstGasForCall (uint32)\n * - tokenOut (address) when `dstGasForCall` > 0\n * - amountOut (uint256) when `dstGasForCall` > 0\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n params.dstGasForCall = stream.readUint32();\n\n if (params.dstGasForCall > 0) {\n // NOTE: `amountIn` is left as zero\n Params memory destParams;\n destParams.partner = t.paramPartner;\n destParams.feeBps = t.paramFeeBps;\n destParams.slippageBps = t.paramSlippageBps;\n destParams.recipient = t.paramRecipient;\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\n // the same address as on this chain\n destParams.tokenIn = t.token;\n destParams.tokenOut = stream.readAddress();\n destParams.amountOut = stream.readUint256();\n destParams.deadline = t.paramDeadline;\n destParams.commands = stream.readBytes();\n params.payload = abi.encode(destParams);\n }\n\n if (t.token != t.paramTokenIn) {\n if (params.payload.length == 0) {\n // If the tokens are being delivered directly to the recipient without a second\n // WarpLink engage, the fee is charged on this chain\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\n // is never charged\n t.amount = LibStarVault.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n }\n\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n t.payer,\n address(this),\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\n\n // Update the payer to this contract\n // TODO: Is this value ever read?\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\n IERC20(t.token).forceApprove(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\n t.amount\n );\n }\n\n t.jumped = 1;\n\n // Swap on the composer if there is a payload, else the router\n IStargateRouter(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\n ).swap{\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\n }({\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\n // more on the other chain. It also assumes the tokens are of nearly equal value\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: params.dstGasForCall,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n // NOTE: This assumes the contract is deployed at the same address on every chain.\n // If this is not the case, a new param needs to be added with the next WarpLink address\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\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\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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable {\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.usePermit = 1;\n\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 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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\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(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy,\n bool use_eth\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\n// Kind 4, uint256s with no return value\n// Example v0.2.15, \"Pool for USDT/BTC/ETH or similar\"\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\ninterface ICurvePoolKind4 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\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/IStargateComposer.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\nimport {IStargateRouter} from './IStargateRouter.sol';\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateComposer is IStargateRouter {\n function stargateRouter() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/IStargateReceiver.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\n\ninterface IStargateReceiver {\n function sgReceive(\n uint16 _srcChainId, // the remote chainId sending the tokens\n bytes memory _srcAddress, // the remote Bridge address\n uint256 _nonce,\n address _token, // the token contract on the local chain\n uint256 amountLD, // the qty of local _token contract tokens\n bytes memory payload\n ) 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n /**\n * A function expecting a permit was used when the input token is ETH\n */\n error PermitForEthToken();\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 curveExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/ILibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibCurve {\n error UnhandledPoolKind();\n}\n" + }, + "contracts/interfaces/ILibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n}\n" + }, + "contracts/interfaces/ILibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n}\n" + }, + "contracts/interfaces/ILibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n}\n" + }, + "contracts/interfaces/IStargate.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\n\ninterface IStargate is ILibStarVault {\n error InsufficientEthValue();\n\n struct JumpTokenParams {\n address token;\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n struct JumpNativeParams {\n /**\n * The amount in is passed to distinguish the amount to bridge from the fee\n */\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable;\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Like is ILibStarVault, ILibWarp {\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 ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Router is ILibStarVault, ILibWarp {\n error EthTransferFailed();\n error ZeroAmountOut();\n error IncorrectEthValue();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\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 error InvalidSgReceiverSender();\n error InvalidSgReceiveSrcAddress();\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 calldata params) external payable;\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable;\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibCurve\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 bool useEth\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 if (useEth) {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\n } else {\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\n }\n } else if (kind == 4) {\n if (underlying) {\n revert UnhandledPoolKind();\n } else {\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * NOTE: Events and errors must be copied to ILibStarVault\n */\nlibrary LibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n\n struct State {\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 uint256 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n /**\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\n * removed to save gas.\n */\n unchecked {\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\n\n assembly {\n s.slot := storagePosition\n }\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 protocolFee\n ) internal {\n State storage s = state();\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit Fee(partner, token, partnerFee, protocolFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint256 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 feeProtocol = feeTotal - feePartner;\n\n if (feeProtocol > 0) {\n registerCollectedFee(partner, token, feePartner, feeProtocol);\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\n/**\n * NOTE: Events and errors must be copied to ILibUniV3Like\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 * Whether to use a permit transfer (0 or 1)\n */\n uint256 usePermit;\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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibWarp\n */\nlibrary LibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateComposer stargateComposer;\n }\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\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/bsc/Curve.json b/packages/hardhat/deployments/bsc/Curve.json index 5d2295dd..69f8d196 100644 --- a/packages/hardhat/deployments/bsc/Curve.json +++ b/packages/hardhat/deployments/bsc/Curve.json @@ -1,5 +1,5 @@ { - "address": "0x84Cd4555CeEA7B0A209232D2E47c316c08bAfDE8", + "address": "0x56880c7B8eE5c4CF8e362bfa4e493B4b6d3245d3", "abi": [ { "inputs": [], @@ -38,6 +38,11 @@ "name": "InsufficientOutputAmount", "type": "error" }, + { + "inputs": [], + "name": "PermitForEthToken", + "type": "error" + }, { "inputs": [], "name": "UnhandledPoolKind", @@ -116,6 +121,97 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "curveExactInputSingle", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -213,7 +309,7 @@ "type": "tuple" } ], - "name": "curveExactInputSingle", + "name": "curveExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -225,28 +321,28 @@ "type": "function" } ], - "transactionHash": "0xbca1c05d0e1aa659badd5078521a82febf050fdaf979e3bb68a27610a001f22d", + "transactionHash": "0x63a344403b2135c13b16d53c5beed5d6b4205b9c131af39b59fb3bc7f1fc557d", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x84Cd4555CeEA7B0A209232D2E47c316c08bAfDE8", - "transactionIndex": 90, - "gasUsed": "1361268", + "contractAddress": "0x56880c7B8eE5c4CF8e362bfa4e493B4b6d3245d3", + "transactionIndex": 51, + "gasUsed": "1468512", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xbaf54c9528bceda1348a262019fdf6c97be105e4af61b77d0abfd1f64deade25", - "transactionHash": "0xbca1c05d0e1aa659badd5078521a82febf050fdaf979e3bb68a27610a001f22d", + "blockHash": "0xacd6da7013b35078cf8ba6ba60e30dfefdcff11f65df930a466510e1219a8f5f", + "transactionHash": "0x63a344403b2135c13b16d53c5beed5d6b4205b9c131af39b59fb3bc7f1fc557d", "logs": [], - "blockNumber": 32959922, - "cumulativeGasUsed": "9336986", + "blockNumber": 33248513, + "cumulativeGasUsed": "5490024", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 7, - "solcInputHash": "ebf955869df0dfecc3a0eb12547e8afc", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 useEth: params.tokenIn == address(0) || isToEth,\\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0x6d796fc46a41bd9fe76ae989d273f90aa0298f993f5c77cf481f5968fad21474\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\\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\":\"0x88d6dcf171951cf8e3f3488ef5d66a953614ae48926f9ace36d58b095bf9dc84\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506117d5806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b6100366100313660046113ad565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906114ed565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff9091169161066b565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b90890189611506565b6040518563ffffffff1660e01b815260040161026a9493929190611572565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b6103cc856101800151866101a001518760600151348961014001518a61016001518b6000015160008073ffffffffffffffffffffffffffffffffffffffff168e60e0015173ffffffffffffffffffffffffffffffffffffffff1614806103c757508a5b6107df565b60008261046d576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046891906114ed565b61046f565b475b905061047b8282611663565b935061048f86602001518760a00151610cdb565b8410156104c8576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ea8660c00151876101000151886080015161ffff16896020015188610d0b565b93508215610596576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610550576040519150601f19603f3d011682016040523d82523d6000602084013e610555565b606091505b5050905080610590576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506105ca565b6105ca86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610dc49092919063ffffffff16565b85610100015173ffffffffffffffffffffffffffffffffffffffff168660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f389600001518860405161065a929190918252602082015260400190565b60405180910390a450505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106f78482610e1f565b6107d95760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526107cf9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610ee0565b6107d98482610ee0565b50505050565b8860ff1660010361090d578715610898576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b5050505050610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610861565b8860ff16600203610a4d5787156109d8576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156109ad573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109d291906114ed565b50610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df0212490889060840161098f565b8860ff16600303610bee578715610acb576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b90889060840161098f565b8015610b45576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a40161098f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015610bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d291906114ed565b8860ff16600403610c9e578715610c31576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610861565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6000612710610cea8382611676565b610cf89061ffff1685611698565b610d0291906116af565b90505b92915050565b60006107d0841115610d52576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610d64575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610d9a5760646032840204610d9d565b60005b9050808303838214610db557610db58a8a8484610fef565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e1a9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161074d565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e49919061170e565b6000604051808303816000865af19150503d8060008114610e86576040519150601f19603f3d011682016040523d82523d6000602084013e610e8b565b606091505b5091509150818015610eb5575080511580610eb5575080806020019051810190610eb5919061172a565b8015610ed7575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166110b79092919063ffffffff16565b9050805160001480610f63575080806020019051810190610f63919061172a565b610e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d49565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60606110c684846000856110ce565b949350505050565b606082471015611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d49565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611189919061170e565b60006040518083038185875af1925050503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b50915091506111dc878383876111e7565b979650505050505050565b6060831561127d5782516000036112765773ffffffffffffffffffffffffffffffffffffffff85163b611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d49565b50816110c6565b6110c683838151156112925781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d49919061174e565b6040516101c0810167ffffffffffffffff81118282101715611311577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133b57600080fd5b919050565b803561ffff8116811461133b57600080fd5b803565ffffffffffff8116811461133b57600080fd5b803560ff8116811461133b57600080fd5b801515811461138757600080fd5b50565b803561133b81611379565b6000604082840312156113a757600080fd5b50919050565b6000808284036101e08112156113c257600080fd5b6101c0808212156113d257600080fd5b6113da6112c6565b915084358252602085013560208301526113f660408601611317565b604083015261140760608601611317565b606083015261141860808601611340565b608083015261142960a08601611340565b60a083015261143a60c08601611317565b60c083015261144b60e08601611317565b60e083015261010061145e818701611317565b90830152610120611470868201611352565b90830152610140611482868201611368565b90830152610160611494868201611368565b908301526101806114a6868201611368565b908301526101a06114b886820161138a565b9083015290925083013567ffffffffffffffff8111156114d757600080fd5b6114e385828601611395565b9150509250929050565b6000602082840312156114ff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261153b57600080fd5b83018035915067ffffffffffffffff82111561155657600080fd5b60200191503681900382131561156b57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d0557610d05611634565b61ffff82811682821603908082111561169157611691611634565b5092915050565b8082028115828204841417610d0557610d05611634565b6000826116e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156117055781810151838201526020016116ed565b50506000910152565b600082516117208184602087016116ea565b9190910192915050565b60006020828403121561173c57600080fd5b815161174781611379565b9392505050565b602081526000825180602084015261176d8160408501602087016116ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212204f164ad9f74d85efb515fab3ce059723b15ff2d1b51c1308c6989e26aff5f0c564736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b6100366100313660046113ad565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906114ed565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff9091169161066b565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b90890189611506565b6040518563ffffffff1660e01b815260040161026a9493929190611572565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b6103cc856101800151866101a001518760600151348961014001518a61016001518b6000015160008073ffffffffffffffffffffffffffffffffffffffff168e60e0015173ffffffffffffffffffffffffffffffffffffffff1614806103c757508a5b6107df565b60008261046d576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046891906114ed565b61046f565b475b905061047b8282611663565b935061048f86602001518760a00151610cdb565b8410156104c8576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ea8660c00151876101000151886080015161ffff16896020015188610d0b565b93508215610596576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610550576040519150601f19603f3d011682016040523d82523d6000602084013e610555565b606091505b5050905080610590576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506105ca565b6105ca86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610dc49092919063ffffffff16565b85610100015173ffffffffffffffffffffffffffffffffffffffff168660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f389600001518860405161065a929190918252602082015260400190565b60405180910390a450505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106f78482610e1f565b6107d95760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526107cf9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610ee0565b6107d98482610ee0565b50505050565b8860ff1660010361090d578715610898576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b5050505050610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610861565b8860ff16600203610a4d5787156109d8576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156109ad573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109d291906114ed565b50610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df0212490889060840161098f565b8860ff16600303610bee578715610acb576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b90889060840161098f565b8015610b45576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a40161098f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015610bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d291906114ed565b8860ff16600403610c9e578715610c31576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610861565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6000612710610cea8382611676565b610cf89061ffff1685611698565b610d0291906116af565b90505b92915050565b60006107d0841115610d52576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610d64575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610d9a5760646032840204610d9d565b60005b9050808303838214610db557610db58a8a8484610fef565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e1a9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161074d565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e49919061170e565b6000604051808303816000865af19150503d8060008114610e86576040519150601f19603f3d011682016040523d82523d6000602084013e610e8b565b606091505b5091509150818015610eb5575080511580610eb5575080806020019051810190610eb5919061172a565b8015610ed7575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166110b79092919063ffffffff16565b9050805160001480610f63575080806020019051810190610f63919061172a565b610e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d49565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60606110c684846000856110ce565b949350505050565b606082471015611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d49565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611189919061170e565b60006040518083038185875af1925050503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b50915091506111dc878383876111e7565b979650505050505050565b6060831561127d5782516000036112765773ffffffffffffffffffffffffffffffffffffffff85163b611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d49565b50816110c6565b6110c683838151156112925781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d49919061174e565b6040516101c0810167ffffffffffffffff81118282101715611311577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133b57600080fd5b919050565b803561ffff8116811461133b57600080fd5b803565ffffffffffff8116811461133b57600080fd5b803560ff8116811461133b57600080fd5b801515811461138757600080fd5b50565b803561133b81611379565b6000604082840312156113a757600080fd5b50919050565b6000808284036101e08112156113c257600080fd5b6101c0808212156113d257600080fd5b6113da6112c6565b915084358252602085013560208301526113f660408601611317565b604083015261140760608601611317565b606083015261141860808601611340565b608083015261142960a08601611340565b60a083015261143a60c08601611317565b60c083015261144b60e08601611317565b60e083015261010061145e818701611317565b90830152610120611470868201611352565b90830152610140611482868201611368565b90830152610160611494868201611368565b908301526101806114a6868201611368565b908301526101a06114b886820161138a565b9083015290925083013567ffffffffffffffff8111156114d757600080fd5b6114e385828601611395565b9150509250929050565b6000602082840312156114ff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261153b57600080fd5b83018035915067ffffffffffffffff82111561155657600080fd5b60200191503681900382131561156b57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d0557610d05611634565b61ffff82811682821603908082111561169157611691611634565b5092915050565b8082028115828204841417610d0557610d05611634565b6000826116e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156117055781810151838201526020016116ed565b50506000910152565b600082516117208184602087016116ea565b9190910192915050565b60006020828403121561173c57600080fd5b815161174781611379565b9392505050565b602081526000825180602084015261176d8160408501602087016116ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212204f164ad9f74d85efb515fab3ce059723b15ff2d1b51c1308c6989e26aff5f0c564736f6c63430008130033", + "numDeployments": 8, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermitForEthToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"name\":\"curveExactInputSingle\",\"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\":\"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\":\"curveExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}],\"PermitForEthToken()\":[{\"notice\":\"A function expecting a permit was used when the input token is ETH\"}]},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\\n * Perform the swap with tokens already moved to this contract\\n */\\n function curveExactInputSingleInternal(\\n ExactInputSingleParams calldata params\\n ) internal returns (uint256 amountOut) {\\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 LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n useEth: params.tokenIn == address(0) || isToEth,\\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function curveExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (params.tokenIn == address(0)) {\\n revert PermitForEthToken();\\n }\\n\\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 return curveExactInputSingleInternal(params);\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\\n }\\n\\n return curveExactInputSingleInternal(params);\\n }\\n}\\n\",\"keccak256\":\"0x14d74eb8ac6efa00532e5de577c6b6ca66866e6991a220986ca7733d920de561\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n /**\\n * A function expecting a permit was used when the input token is ETH\\n */\\n error PermitForEthToken();\\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 curveExactInputSinglePermit(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xd034586f038b6ea01e6ce9d6497d203ef8cc5d221884f1a6f608ce08bae51904\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506119c8806100206000396000f3fe6080604052600436106100295760003560e01c806356bf88f01461002e578063aef417b114610053575b600080fd5b61004161003c366004611598565b610066565b60405190815260200160405180910390f35b6100416100613660046115f0565b610348565b60008061007a610100850160e0860161160d565b73ffffffffffffffffffffffffffffffffffffffff16036100c7576040517f53e40ce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a6100da608085016060860161160d565b84356100ed610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff169190610430565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925273ffffffffffffffffffffffffffffffffffffffff90921691632b67b57091339190819060608201908190610174906101008c01908c0161160d565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016101ab6101408b016101208c0161164a565b65ffffffffffff908116825289351660209182015290825230908201526040016101dd61014089016101208a0161164a565b65ffffffffffff1690526101f46020870187611672565b6040518563ffffffff1660e01b815260040161021394939291906116de565b600060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505061026c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333086356102a0610100890160e08a0161160d565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561031e57600080fd5b505af1158015610332573d6000803e3d6000fd5b5050505061033f836105a4565b90505b92915050565b600061035c6101408301610120840161164a565b65ffffffffffff1642111561039d576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103b0610100840160e0850161160d565b73ffffffffffffffffffffffffffffffffffffffff1614610427576103f16103de608084016060850161160d565b83356100ed610100860160e0870161160d565b61042733308435610409610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff16929190610a43565b610342826105a4565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526104bc8482610aa1565b61059e5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526105949085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610b62565b61059e8482610b62565b50505050565b600080806105ba6101208501610100860161160d565b73ffffffffffffffffffffffffffffffffffffffff16149050600081610681576105ec6101208501610100860161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c91906117a0565b610683565b475b905061073661069a6101a0860161018087016117b9565b6106ac6101c087016101a088016117ed565b6106bc608088016060890161160d565b346106cf6101608a016101408b016117b9565b6106e16101808b016101608c016117b9565b8a6000013560008073ffffffffffffffffffffffffffffffffffffffff168d60e0016020810190610712919061160d565b73ffffffffffffffffffffffffffffffffffffffff16148061073157508a5b610c7b565b6000826107e45761074f6101208601610100870161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df91906117a0565b6107e6565b475b90506107f28282611839565b9350610811602086013561080c60c0880160a0890161184c565b611177565b84101561084a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088e61085d60e0870160c0880161160d565b61086f6101208801610100890161160d565b61087f60a0890160808a0161184c565b61ffff1688602001358861119e565b935082156109455760006108a8606087016040880161160d565b73ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146108ff576040519150601f19603f3d011682016040523d82523d6000602084013e610904565b606091505b505090508061093f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610988565b610988610958606087016040880161160d565b8561096b61012089016101008a0161160d565b73ffffffffffffffffffffffffffffffffffffffff169190611252565b61099a6101208601610100870161160d565b73ffffffffffffffffffffffffffffffffffffffff166109c1610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff166109e760e0880160c0890161160d565b60408051893581526020810189905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261059e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610512565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610acb9190611894565b6000604051808303816000865af19150503d8060008114610b08576040519150601f19603f3d011682016040523d82523d6000602084013e610b0d565b606091505b5091509150818015610b37575080511580610b37575080806020019051810190610b3791906118b0565b8015610b59575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610bc4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112a89092919063ffffffff16565b9050805160001480610be5575080806020019051810190610be591906118b0565b610c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b8860ff16600103610da9578715610d34576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015610d1657600080fd5b505af1158015610d2a573d6000803e3d6000fd5b505050505061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610cfd565b8860ff16600203610ee9578715610e74576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015610e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b5061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610e2b565b8860ff1660030361108a578715610f67576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401610e2b565b8015610fe1576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401610e2b565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015611066573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b8860ff1660040361113a5787156110cd576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610cfd565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600061271061118683826118cd565b6111949061ffff16856118ef565b61033f9190611906565b60006107d08411156111e0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d06004820152602401610c6d565b600082848111156111f2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611228576064603284020461122b565b60005b9050808303838214611243576112438a8a84846112bf565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c769084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610512565b60606112b78484600085611387565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606082471015611419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c6d565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516114429190611894565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b5091509150611495878383876114a0565b979650505050505050565b6060831561153657825160000361152f5773ffffffffffffffffffffffffffffffffffffffff85163b61152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c6d565b50816112b7565b6112b7838381511561154b5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9190611941565b60006101c0828403121561159257600080fd5b50919050565b6000806101e083850312156115ac57600080fd5b6115b6848461157f565b91506101c083013567ffffffffffffffff8111156115d357600080fd5b8301604081860312156115e557600080fd5b809150509250929050565b60006101c0828403121561160357600080fd5b61033f838361157f565b60006020828403121561161f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461164357600080fd5b9392505050565b60006020828403121561165c57600080fd5b813565ffffffffffff8116811461164357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126116a757600080fd5b83018035915067ffffffffffffffff8211156116c257600080fd5b6020019150368190038213156116d757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156117b257600080fd5b5051919050565b6000602082840312156117cb57600080fd5b813560ff8116811461164357600080fd5b80151581146117ea57600080fd5b50565b6000602082840312156117ff57600080fd5b8135611643816117dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156103425761034261180a565b60006020828403121561185e57600080fd5b813561ffff8116811461164357600080fd5b60005b8381101561188b578181015183820152602001611873565b50506000910152565b600082516118a6818460208701611870565b9190910192915050565b6000602082840312156118c257600080fd5b8151611643816117dc565b61ffff8281168282160390808211156118e8576118e861180a565b5092915050565b80820281158282048414176103425761034261180a565b60008261193c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6020815260008251806020840152611960816040850160208701611870565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202b55d2f11aa7f1395a3e9c79ad5594ecdb6d8158214c767aed2d3da3a5500d1264736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c806356bf88f01461002e578063aef417b114610053575b600080fd5b61004161003c366004611598565b610066565b60405190815260200160405180910390f35b6100416100613660046115f0565b610348565b60008061007a610100850160e0860161160d565b73ffffffffffffffffffffffffffffffffffffffff16036100c7576040517f53e40ce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a6100da608085016060860161160d565b84356100ed610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff169190610430565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925273ffffffffffffffffffffffffffffffffffffffff90921691632b67b57091339190819060608201908190610174906101008c01908c0161160d565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016101ab6101408b016101208c0161164a565b65ffffffffffff908116825289351660209182015290825230908201526040016101dd61014089016101208a0161164a565b65ffffffffffff1690526101f46020870187611672565b6040518563ffffffff1660e01b815260040161021394939291906116de565b600060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505061026c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333086356102a0610100890160e08a0161160d565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561031e57600080fd5b505af1158015610332573d6000803e3d6000fd5b5050505061033f836105a4565b90505b92915050565b600061035c6101408301610120840161164a565b65ffffffffffff1642111561039d576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103b0610100840160e0850161160d565b73ffffffffffffffffffffffffffffffffffffffff1614610427576103f16103de608084016060850161160d565b83356100ed610100860160e0870161160d565b61042733308435610409610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff16929190610a43565b610342826105a4565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526104bc8482610aa1565b61059e5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526105949085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610b62565b61059e8482610b62565b50505050565b600080806105ba6101208501610100860161160d565b73ffffffffffffffffffffffffffffffffffffffff16149050600081610681576105ec6101208501610100860161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c91906117a0565b610683565b475b905061073661069a6101a0860161018087016117b9565b6106ac6101c087016101a088016117ed565b6106bc608088016060890161160d565b346106cf6101608a016101408b016117b9565b6106e16101808b016101608c016117b9565b8a6000013560008073ffffffffffffffffffffffffffffffffffffffff168d60e0016020810190610712919061160d565b73ffffffffffffffffffffffffffffffffffffffff16148061073157508a5b610c7b565b6000826107e45761074f6101208601610100870161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df91906117a0565b6107e6565b475b90506107f28282611839565b9350610811602086013561080c60c0880160a0890161184c565b611177565b84101561084a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088e61085d60e0870160c0880161160d565b61086f6101208801610100890161160d565b61087f60a0890160808a0161184c565b61ffff1688602001358861119e565b935082156109455760006108a8606087016040880161160d565b73ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146108ff576040519150601f19603f3d011682016040523d82523d6000602084013e610904565b606091505b505090508061093f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610988565b610988610958606087016040880161160d565b8561096b61012089016101008a0161160d565b73ffffffffffffffffffffffffffffffffffffffff169190611252565b61099a6101208601610100870161160d565b73ffffffffffffffffffffffffffffffffffffffff166109c1610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff166109e760e0880160c0890161160d565b60408051893581526020810189905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261059e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610512565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610acb9190611894565b6000604051808303816000865af19150503d8060008114610b08576040519150601f19603f3d011682016040523d82523d6000602084013e610b0d565b606091505b5091509150818015610b37575080511580610b37575080806020019051810190610b3791906118b0565b8015610b59575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610bc4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112a89092919063ffffffff16565b9050805160001480610be5575080806020019051810190610be591906118b0565b610c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b8860ff16600103610da9578715610d34576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015610d1657600080fd5b505af1158015610d2a573d6000803e3d6000fd5b505050505061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610cfd565b8860ff16600203610ee9578715610e74576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015610e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b5061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610e2b565b8860ff1660030361108a578715610f67576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401610e2b565b8015610fe1576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401610e2b565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015611066573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b8860ff1660040361113a5787156110cd576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610cfd565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600061271061118683826118cd565b6111949061ffff16856118ef565b61033f9190611906565b60006107d08411156111e0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d06004820152602401610c6d565b600082848111156111f2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611228576064603284020461122b565b60005b9050808303838214611243576112438a8a84846112bf565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c769084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610512565b60606112b78484600085611387565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606082471015611419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c6d565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516114429190611894565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b5091509150611495878383876114a0565b979650505050505050565b6060831561153657825160000361152f5773ffffffffffffffffffffffffffffffffffffffff85163b61152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c6d565b50816112b7565b6112b7838381511561154b5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9190611941565b60006101c0828403121561159257600080fd5b50919050565b6000806101e083850312156115ac57600080fd5b6115b6848461157f565b91506101c083013567ffffffffffffffff8111156115d357600080fd5b8301604081860312156115e557600080fd5b809150509250929050565b60006101c0828403121561160357600080fd5b61033f838361157f565b60006020828403121561161f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461164357600080fd5b9392505050565b60006020828403121561165c57600080fd5b813565ffffffffffff8116811461164357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126116a757600080fd5b83018035915067ffffffffffffffff8211156116c257600080fd5b6020019150368190038213156116d757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156117b257600080fd5b5051919050565b6000602082840312156117cb57600080fd5b813560ff8116811461164357600080fd5b80151581146117ea57600080fd5b50565b6000602082840312156117ff57600080fd5b8135611643816117dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156103425761034261180a565b60006020828403121561185e57600080fd5b813561ffff8116811461164357600080fd5b60005b8381101561188b578181015183820152602001611873565b50506000910152565b600082516118a6818460208701611870565b9190910192915050565b6000602082840312156118c257600080fd5b8151611643816117dc565b61ffff8281168282160390808211156118e8576118e861180a565b5092915050565b80820281158282048414176103425761034261180a565b60008261193c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6020815260008251806020840152611960816040850160208701611870565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202b55d2f11aa7f1395a3e9c79ad5594ecdb6d8158214c767aed2d3da3a5500d1264736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, @@ -261,6 +357,11 @@ { "notice": "The swap fee is over the maximum allowed" } + ], + "PermitForEthToken()": [ + { + "notice": "A function expecting a permit was used when the input token is ETH" + } ] }, "kind": "user", diff --git a/packages/hardhat/deployments/bsc/Stargate.json b/packages/hardhat/deployments/bsc/Stargate.json index f1cc043b..b8d18f58 100644 --- a/packages/hardhat/deployments/bsc/Stargate.json +++ b/packages/hardhat/deployments/bsc/Stargate.json @@ -1,5 +1,5 @@ { - "address": "0xBc3DF9Aa6223128F517fDb3C93d51B1a28F0f96A", + "address": "0x352AfE52B0972d67148C01690cB90281fBF6bC35", "abi": [ { "inputs": [ @@ -124,6 +124,76 @@ "stateMutability": "payable", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint160", + "name": "amountIn", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "amountOutExpected", + "type": "uint160" + }, + { + "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": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "srcPoolId", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "dstPoolId", + "type": "uint8" + } + ], + "internalType": "struct IStargate.JumpTokenParams", + "name": "params", + "type": "tuple" + } + ], + "name": "stargateJumpToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -206,34 +276,34 @@ "type": "tuple" } ], - "name": "stargateJumpToken", + "name": "stargateJumpTokenPermit", "outputs": [], "stateMutability": "payable", "type": "function" } ], - "transactionHash": "0x66161a206962e2b8d3c2140ad53ec953ac5eb82c3b1bf572efe377265b56b0d4", + "transactionHash": "0x6ce38e9e63407d522893ac2a4004455705148b530004d0c377c002d909b24826", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xBc3DF9Aa6223128F517fDb3C93d51B1a28F0f96A", - "transactionIndex": 88, - "gasUsed": "1184682", + "contractAddress": "0x352AfE52B0972d67148C01690cB90281fBF6bC35", + "transactionIndex": 71, + "gasUsed": "1254228", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xb6ab5cf168e501dd05191ec29afdde8f0cec0c114394c1c7c77fc91c9bdfb045", - "transactionHash": "0x66161a206962e2b8d3c2140ad53ec953ac5eb82c3b1bf572efe377265b56b0d4", + "blockHash": "0x5aff2504383d27cd22862a4433743334680b0a9c4267b0e1ea675303aafc6da7", + "transactionHash": "0x6ce38e9e63407d522893ac2a4004455705148b530004d0c377c002d909b24826", "logs": [], - "blockNumber": 32736478, - "cumulativeGasUsed": "10719573", + "blockNumber": 33248529, + "cumulativeGasUsed": "6890889", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpNativeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"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\":\"stargateJumpToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Stargate.sol\":\"Stargate\"},\"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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract Stargate is IStargate {\\n using SafeERC20 for IERC20;\\n\\n function stargateJumpToken(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.token,\\n amount: 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 // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n uint160(params.amountIn),\\n params.token\\n );\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.token,\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n // NOTE: This lookup is spending 319 gas\\n IStargateRouter stargateRouter = IStargateRouter(\\n LibWarp.state().stargateComposer.stargateRouter()\\n );\\n\\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\\n\\n unchecked {\\n stargateRouter.swap{value: msg.value}({\\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\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n address(0),\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n unchecked {\\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n}\\n\",\"keccak256\":\"0x384ff4fd006f55fd52c6532724722c9d8709db7760e8296c8a9447a19bd148f1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/IStargate.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\n\\ninterface IStargate is ILibStarVault {\\n error InsufficientEthValue();\\n\\n struct JumpTokenParams {\\n address token;\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n struct JumpNativeParams {\\n /**\\n * The amount in is passed to distinguish the amount to bridge from the fee\\n */\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n function stargateJumpToken(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\\n}\\n\",\"keccak256\":\"0x4464ecac16a3c449c8f7983ac21ba54a44ac02194baa590c480b6ffc1cddd478\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b5061148c806100206000396000f3fe6080604052600436106100295760003560e01c806329859a061461002e578063c2bee2af14610043575b600080fd5b61004161003c366004610fca565b610056565b005b610041610051366004611029565b610618565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100b760208a018a611067565b73ffffffffffffffffffffffffffffffffffffffff1681526020018860200160208101906100e59190611067565b73ffffffffffffffffffffffffffffffffffffffff16815260200161011060e08a0160c08b0161108b565b65ffffffffffff9081168252883516602091820152908252309082015260400161014060e0880160c0890161108b565b65ffffffffffff16905261015760208601866110b3565b6040518563ffffffff1660e01b8152600401610176949392919061111f565b600060405180830381600087803b15801561019057600080fd5b505af11580156101a4573d6000803e3d6000fd5b505050506101cf7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633306102006040870160208801611067565b61020d6020880188611067565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561028b57600080fd5b505af115801561029f573d6000803e3d6000fd5b50505050600061032d8360e00160208101906102bb9190611067565b6102c86020860186611067565b6102d860c0870160a088016111e1565b61ffff166102ec6040880160208901611067565b73ffffffffffffffffffffffffffffffffffffffff166103126040890160208a01611067565b73ffffffffffffffffffffffffffffffffffffffff16610905565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190611205565b905061041581836103f86020880188611067565b73ffffffffffffffffffffffffffffffffffffffff1691906109be565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc34610444610120880161010089016111e1565b61045661014089016101208a01611222565b6104686101608a016101408b01611222565b33888061047b60408e0160208f01611067565b73ffffffffffffffffffffffffffffffffffffffff16036104a260608e0160408f01611067565b73ffffffffffffffffffffffffffffffffffffffff16116104c4576000610534565b6105348a8d60200160208101906104db9190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d60400160208101906105059190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d608001602081019061052f91906111e1565b610aee565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508d60600160208101906105739190611067565b6040516020016105ae919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016105e09897969594939291906112b3565b6000604051808303818588803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050505050505050565b6106256020820182611067565b73ffffffffffffffffffffffffffffffffffffffff16341015610674576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106cf61068960e0840160c08501611067565b600061069b60a08601608087016111e1565b61ffff166106ac6020870187611067565b73ffffffffffffffffffffffffffffffffffffffff166103126020880188611067565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261071d6020860186611067565b73ffffffffffffffffffffffffffffffffffffffff16033403610747610100860160e087016111e1565b61075961012087016101008801611222565b61076b61014088016101208901611222565b33878061077b60208c018c611067565b73ffffffffffffffffffffffffffffffffffffffff16036107a260408c0160208d01611067565b73ffffffffffffffffffffffffffffffffffffffff16116107c4576000610823565b610823896107d560208d018d611067565b73ffffffffffffffffffffffffffffffffffffffff16036107fc60408d0160208e01611067565b73ffffffffffffffffffffffffffffffffffffffff160361052f60808d0160608e016111e1565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b60400160208101906108629190611067565b60405160200161089d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016108cf9897969594939291906112b3565b6000604051808303818588803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b50505050505050565b60006107d084111561094c576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561095e575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109945760646032840204610997565b60005b90508083038382146109af576109af8a8a8484610b1e565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610a4a8482610be6565b610ae8576040805173ffffffffffffffffffffffffffffffffffffffff8516602482015260006044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610ade908590610ca7565b610ae88482610ca7565b50505050565b6000612710610afd8382611391565b610b0b9061ffff16856113b3565b610b1591906113ca565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c109190611405565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611421565b8015610c9e575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610dbb9092919063ffffffff16565b9050805160001480610d2a575080806020019051810190610d2a9190611421565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610943565b505050565b6060610dca8484600085610dd2565b949350505050565b606082471015610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610943565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610e8d9190611405565b60006040518083038185875af1925050503d8060008114610eca576040519150601f19603f3d011682016040523d82523d6000602084013e610ecf565b606091505b5091509150610ee087838387610eeb565b979650505050505050565b60608315610f81578251600003610f7a5773ffffffffffffffffffffffffffffffffffffffff85163b610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b5081610dca565b610dca8383815115610f965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109439190611443565b600080828403610180811215610fdf57600080fd5b61016080821215610fef57600080fd5b849350830135905067ffffffffffffffff81111561100c57600080fd5b83016040818603121561101e57600080fd5b809150509250929050565b6000610140828403121561103c57600080fd5b50919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461106457600080fd5b50565b60006020828403121561107957600080fd5b813561108481611042565b9392505050565b60006020828403121561109d57600080fd5b813565ffffffffffff8116811461108457600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110e857600080fd5b83018035915067ffffffffffffffff82111561110357600080fd5b60200191503681900382131561111857600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156111f357600080fd5b813561ffff8116811461108457600080fd5b60006020828403121561121757600080fd5b815161108481611042565b60006020828403121561123457600080fd5b813560ff8116811461108457600080fd5b60005b83811015611260578181015183820152602001611248565b50506000910152565b60008151808452611281816020860160208601611245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c08401528451818401525060208401516101408301526040840151606061016084015261132c610180840182611269565b905082810360e08401526113408185611269565b838103610100850152600081529050602081019b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156113ac576113ac611362565b5092915050565b8082028115828204841417610b1857610b18611362565b600082611400577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251611417818460208701611245565b9190910192915050565b60006020828403121561143357600080fd5b8151801515811461108457600080fd5b602081526000610b15602083018461126956fea2646970667358221220fd4949e43a56ae6a92fdbb921568c2bc2a7013da24304d0b873ce9c5e7515c0264736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806329859a061461002e578063c2bee2af14610043575b600080fd5b61004161003c366004610fca565b610056565b005b610041610051366004611029565b610618565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100b760208a018a611067565b73ffffffffffffffffffffffffffffffffffffffff1681526020018860200160208101906100e59190611067565b73ffffffffffffffffffffffffffffffffffffffff16815260200161011060e08a0160c08b0161108b565b65ffffffffffff9081168252883516602091820152908252309082015260400161014060e0880160c0890161108b565b65ffffffffffff16905261015760208601866110b3565b6040518563ffffffff1660e01b8152600401610176949392919061111f565b600060405180830381600087803b15801561019057600080fd5b505af11580156101a4573d6000803e3d6000fd5b505050506101cf7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633306102006040870160208801611067565b61020d6020880188611067565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561028b57600080fd5b505af115801561029f573d6000803e3d6000fd5b50505050600061032d8360e00160208101906102bb9190611067565b6102c86020860186611067565b6102d860c0870160a088016111e1565b61ffff166102ec6040880160208901611067565b73ffffffffffffffffffffffffffffffffffffffff166103126040890160208a01611067565b73ffffffffffffffffffffffffffffffffffffffff16610905565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190611205565b905061041581836103f86020880188611067565b73ffffffffffffffffffffffffffffffffffffffff1691906109be565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc34610444610120880161010089016111e1565b61045661014089016101208a01611222565b6104686101608a016101408b01611222565b33888061047b60408e0160208f01611067565b73ffffffffffffffffffffffffffffffffffffffff16036104a260608e0160408f01611067565b73ffffffffffffffffffffffffffffffffffffffff16116104c4576000610534565b6105348a8d60200160208101906104db9190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d60400160208101906105059190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d608001602081019061052f91906111e1565b610aee565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508d60600160208101906105739190611067565b6040516020016105ae919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016105e09897969594939291906112b3565b6000604051808303818588803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050505050505050565b6106256020820182611067565b73ffffffffffffffffffffffffffffffffffffffff16341015610674576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106cf61068960e0840160c08501611067565b600061069b60a08601608087016111e1565b61ffff166106ac6020870187611067565b73ffffffffffffffffffffffffffffffffffffffff166103126020880188611067565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261071d6020860186611067565b73ffffffffffffffffffffffffffffffffffffffff16033403610747610100860160e087016111e1565b61075961012087016101008801611222565b61076b61014088016101208901611222565b33878061077b60208c018c611067565b73ffffffffffffffffffffffffffffffffffffffff16036107a260408c0160208d01611067565b73ffffffffffffffffffffffffffffffffffffffff16116107c4576000610823565b610823896107d560208d018d611067565b73ffffffffffffffffffffffffffffffffffffffff16036107fc60408d0160208e01611067565b73ffffffffffffffffffffffffffffffffffffffff160361052f60808d0160608e016111e1565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b60400160208101906108629190611067565b60405160200161089d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016108cf9897969594939291906112b3565b6000604051808303818588803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b50505050505050565b60006107d084111561094c576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561095e575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109945760646032840204610997565b60005b90508083038382146109af576109af8a8a8484610b1e565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610a4a8482610be6565b610ae8576040805173ffffffffffffffffffffffffffffffffffffffff8516602482015260006044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610ade908590610ca7565b610ae88482610ca7565b50505050565b6000612710610afd8382611391565b610b0b9061ffff16856113b3565b610b1591906113ca565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c109190611405565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611421565b8015610c9e575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610dbb9092919063ffffffff16565b9050805160001480610d2a575080806020019051810190610d2a9190611421565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610943565b505050565b6060610dca8484600085610dd2565b949350505050565b606082471015610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610943565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610e8d9190611405565b60006040518083038185875af1925050503d8060008114610eca576040519150601f19603f3d011682016040523d82523d6000602084013e610ecf565b606091505b5091509150610ee087838387610eeb565b979650505050505050565b60608315610f81578251600003610f7a5773ffffffffffffffffffffffffffffffffffffffff85163b610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b5081610dca565b610dca8383815115610f965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109439190611443565b600080828403610180811215610fdf57600080fd5b61016080821215610fef57600080fd5b849350830135905067ffffffffffffffff81111561100c57600080fd5b83016040818603121561101e57600080fd5b809150509250929050565b6000610140828403121561103c57600080fd5b50919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461106457600080fd5b50565b60006020828403121561107957600080fd5b813561108481611042565b9392505050565b60006020828403121561109d57600080fd5b813565ffffffffffff8116811461108457600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110e857600080fd5b83018035915067ffffffffffffffff82111561110357600080fd5b60200191503681900382131561111857600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156111f357600080fd5b813561ffff8116811461108457600080fd5b60006020828403121561121757600080fd5b815161108481611042565b60006020828403121561123457600080fd5b813560ff8116811461108457600080fd5b60005b83811015611260578181015183820152602001611248565b50506000910152565b60008151808452611281816020860160208601611245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c08401528451818401525060208401516101408301526040840151606061016084015261132c610180840182611269565b905082810360e08401526113408185611269565b838103610100850152600081529050602081019b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156113ac576113ac611362565b5092915050565b8082028115828204841417610b1857610b18611362565b600082611400577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251611417818460208701611245565b9190910192915050565b60006020828403121561143357600080fd5b8151801515811461108457600080fd5b602081526000610b15602083018461126956fea2646970667358221220fd4949e43a56ae6a92fdbb921568c2bc2a7013da24304d0b873ce9c5e7515c0264736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpNativeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"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\":\"stargateJumpTokenPermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Stargate.sol\":\"Stargate\"},\"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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract Stargate is IStargate {\\n using SafeERC20 for IERC20;\\n\\n /**\\n * Jump tokens with Stargate with input tokens already moved to this contract\\n */\\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.token,\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n // NOTE: This lookup is spending 319 gas\\n IStargateRouter stargateRouter = IStargateRouter(\\n LibWarp.state().stargateComposer.stargateRouter()\\n );\\n\\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\\n\\n unchecked {\\n stargateRouter.swap{value: msg.value}({\\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\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n\\n function stargateJumpTokenPermit(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.token,\\n amount: 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 // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n uint160(params.amountIn),\\n params.token\\n );\\n\\n stargateJumpTokenInternal(params);\\n }\\n\\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\\n // Transfer tokens from the sender to this contract\\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\\n\\n stargateJumpTokenInternal(params);\\n }\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n address(0),\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n unchecked {\\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6abe4954877eed5b5a9c473441ac11e6f505d6cedc5c1d9489960227c5fb6f84\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/IStargate.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\n\\ninterface IStargate is ILibStarVault {\\n error InsufficientEthValue();\\n\\n struct JumpTokenParams {\\n address token;\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n struct JumpNativeParams {\\n /**\\n * The amount in is passed to distinguish the amount to bridge from the fee\\n */\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\\n\\n function stargateJumpTokenPermit(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\\n}\\n\",\"keccak256\":\"0xb35bd721e5ab9f7cd120a61bdafd807dcebd1cf71f5189662697f47a1f10986c\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506115d1806100206000396000f3fe6080604052600436106100345760003560e01c80638be9f27914610039578063ba2466d41461004e578063c2bee2af14610061575b600080fd5b61004c610047366004611102565b610074565b005b61004c61005c36600461115a565b6102ce565b61004c61006f366004611177565b610330565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100d560208a018a6111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200188602001602081019061010391906111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200161012e60e08a0160c08b016111d0565b65ffffffffffff9081168252883516602091820152908252309082015260400161015e60e0880160c089016111d0565b65ffffffffffff16905261017560208601866111f8565b6040518563ffffffff1660e01b81526004016101949493929190611264565b600060405180830381600087803b1580156101ae57600080fd5b505af11580156101c2573d6000803e3d6000fd5b505050506101ed7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333061021e60408701602088016111ac565b61022b60208801886111ac565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102a957600080fd5b505af11580156102bd573d6000803e3d6000fd5b505050506102ca8261063d565b5050565b61032433306102e360408501602086016111ac565b73ffffffffffffffffffffffffffffffffffffffff1661030660208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff16929190610986565b61032d8161063d565b50565b61033d60208201826111ac565b73ffffffffffffffffffffffffffffffffffffffff1634101561038c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104026103a160e0840160c085016111ac565b60006103b360a0860160808701611326565b61ffff166103c460208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760208801886111ac565b73ffffffffffffffffffffffffffffffffffffffff16610a68565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261045060208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff1603340361047a610100860160e08701611326565b61048c6101208701610100880161134a565b61049e6101408801610120890161134a565b3387806104ae60208c018c6111ac565b73ffffffffffffffffffffffffffffffffffffffff16036104d560408c0160208d016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116104f757600061055b565b61055b8961050860208d018d6111ac565b73ffffffffffffffffffffffffffffffffffffffff160361052f60408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660808d0160608e01611326565b610b21565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b604001602081019061059a91906111ac565b6040516020016105d5919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016106079897969594939291906113db565b6000604051808303818588803b15801561062057600080fd5b505af1158015610634573d6000803e3d6000fd5b50505050505050565b60006106aa610653610100840160e085016111ac565b61066060208501856111ac565b61067060c0860160a08701611326565b61ffff1661068460408701602088016111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760408801602089016111ac565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610761919061148a565b9050610792818361077560208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff169190610b51565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc346107c161012087016101008801611326565b6107d36101408801610120890161134a565b6107e561016089016101408a0161134a565b3388806107f860408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361081f60608d0160408e016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116108415760006108a3565b6108a38a61085560408e0160208f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361087c60608e0160408f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660a08e0160808f01611326565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60600160208101906108e291906111ac565b60405160200161091d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b815260040161094f9897969594939291906113db565b6000604051808303818588803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a629085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610c3d565b50505050565b60006107d0841115610aaf576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610ac1575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610af75760646032840204610afa565b60005b9050808303838214610b1257610b128a8a8484610d51565b50505090910395945050505050565b6000612710610b3083826114d6565b610b3e9061ffff16856114f8565b610b48919061150f565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610bdd8482610e19565b610a625760405173ffffffffffffffffffffffffffffffffffffffff8416602482015260006044820152610c379085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109e0565b610a6284825b6000610c9f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610eda9092919063ffffffff16565b9050805160001480610cc0575080806020019051810190610cc0919061154a565b610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa6565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e43919061156c565b6000604051808303816000865af19150503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5091509150818015610eaf575080511580610eaf575080806020019051810190610eaf919061154a565b8015610ed1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060610ee98484600085610ef1565b949350505050565b606082471015610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fac919061156c565b60006040518083038185875af1925050503d8060008114610fe9576040519150601f19603f3d011682016040523d82523d6000602084013e610fee565b606091505b5091509150610fff8783838761100a565b979650505050505050565b606083156110a05782516000036110995773ffffffffffffffffffffffffffffffffffffffff85163b611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa6565b5081610ee9565b610ee983838151156110b55781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa69190611588565b600061016082840312156110fc57600080fd5b50919050565b600080610180838503121561111657600080fd5b61112084846110e9565b915061016083013567ffffffffffffffff81111561113d57600080fd5b83016040818603121561114f57600080fd5b809150509250929050565b6000610160828403121561116d57600080fd5b610b4883836110e9565b600061014082840312156110fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461032d57600080fd5b6000602082840312156111be57600080fd5b81356111c98161118a565b9392505050565b6000602082840312156111e257600080fd5b813565ffffffffffff811681146111c957600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261122d57600080fd5b83018035915067ffffffffffffffff82111561124857600080fd5b60200191503681900382131561125d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60006020828403121561133857600080fd5b813561ffff811681146111c957600080fd5b60006020828403121561135c57600080fd5b813560ff811681146111c957600080fd5b60005b83811015611388578181015183820152602001611370565b50506000910152565b600081518084526113a981602086016020860161136d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c084015284518184015250602084015161014083015260408401516060610160840152611454610180840182611391565b905082810360e08401526114688185611391565b838103610100850152600081529050602081019b9a5050505050505050505050565b60006020828403121561149c57600080fd5b81516111c98161118a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156114f1576114f16114a7565b5092915050565b8082028115828204841417610b4b57610b4b6114a7565b600082611545577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561155c57600080fd5b815180151581146111c957600080fd5b6000825161157e81846020870161136d565b9190910192915050565b602081526000610b48602083018461139156fea26469706673582212208328d8149ca8eb632152123f06714fc50d6667b0823eba29b328ace315d4e37464736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c80638be9f27914610039578063ba2466d41461004e578063c2bee2af14610061575b600080fd5b61004c610047366004611102565b610074565b005b61004c61005c36600461115a565b6102ce565b61004c61006f366004611177565b610330565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100d560208a018a6111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200188602001602081019061010391906111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200161012e60e08a0160c08b016111d0565b65ffffffffffff9081168252883516602091820152908252309082015260400161015e60e0880160c089016111d0565b65ffffffffffff16905261017560208601866111f8565b6040518563ffffffff1660e01b81526004016101949493929190611264565b600060405180830381600087803b1580156101ae57600080fd5b505af11580156101c2573d6000803e3d6000fd5b505050506101ed7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333061021e60408701602088016111ac565b61022b60208801886111ac565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102a957600080fd5b505af11580156102bd573d6000803e3d6000fd5b505050506102ca8261063d565b5050565b61032433306102e360408501602086016111ac565b73ffffffffffffffffffffffffffffffffffffffff1661030660208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff16929190610986565b61032d8161063d565b50565b61033d60208201826111ac565b73ffffffffffffffffffffffffffffffffffffffff1634101561038c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104026103a160e0840160c085016111ac565b60006103b360a0860160808701611326565b61ffff166103c460208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760208801886111ac565b73ffffffffffffffffffffffffffffffffffffffff16610a68565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261045060208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff1603340361047a610100860160e08701611326565b61048c6101208701610100880161134a565b61049e6101408801610120890161134a565b3387806104ae60208c018c6111ac565b73ffffffffffffffffffffffffffffffffffffffff16036104d560408c0160208d016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116104f757600061055b565b61055b8961050860208d018d6111ac565b73ffffffffffffffffffffffffffffffffffffffff160361052f60408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660808d0160608e01611326565b610b21565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b604001602081019061059a91906111ac565b6040516020016105d5919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016106079897969594939291906113db565b6000604051808303818588803b15801561062057600080fd5b505af1158015610634573d6000803e3d6000fd5b50505050505050565b60006106aa610653610100840160e085016111ac565b61066060208501856111ac565b61067060c0860160a08701611326565b61ffff1661068460408701602088016111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760408801602089016111ac565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610761919061148a565b9050610792818361077560208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff169190610b51565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc346107c161012087016101008801611326565b6107d36101408801610120890161134a565b6107e561016089016101408a0161134a565b3388806107f860408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361081f60608d0160408e016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116108415760006108a3565b6108a38a61085560408e0160208f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361087c60608e0160408f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660a08e0160808f01611326565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60600160208101906108e291906111ac565b60405160200161091d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b815260040161094f9897969594939291906113db565b6000604051808303818588803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a629085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610c3d565b50505050565b60006107d0841115610aaf576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610ac1575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610af75760646032840204610afa565b60005b9050808303838214610b1257610b128a8a8484610d51565b50505090910395945050505050565b6000612710610b3083826114d6565b610b3e9061ffff16856114f8565b610b48919061150f565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610bdd8482610e19565b610a625760405173ffffffffffffffffffffffffffffffffffffffff8416602482015260006044820152610c379085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109e0565b610a6284825b6000610c9f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610eda9092919063ffffffff16565b9050805160001480610cc0575080806020019051810190610cc0919061154a565b610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa6565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e43919061156c565b6000604051808303816000865af19150503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5091509150818015610eaf575080511580610eaf575080806020019051810190610eaf919061154a565b8015610ed1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060610ee98484600085610ef1565b949350505050565b606082471015610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fac919061156c565b60006040518083038185875af1925050503d8060008114610fe9576040519150601f19603f3d011682016040523d82523d6000602084013e610fee565b606091505b5091509150610fff8783838761100a565b979650505050505050565b606083156110a05782516000036110995773ffffffffffffffffffffffffffffffffffffffff85163b611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa6565b5081610ee9565b610ee983838151156110b55781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa69190611588565b600061016082840312156110fc57600080fd5b50919050565b600080610180838503121561111657600080fd5b61112084846110e9565b915061016083013567ffffffffffffffff81111561113d57600080fd5b83016040818603121561114f57600080fd5b809150509250929050565b6000610160828403121561116d57600080fd5b610b4883836110e9565b600061014082840312156110fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461032d57600080fd5b6000602082840312156111be57600080fd5b81356111c98161118a565b9392505050565b6000602082840312156111e257600080fd5b813565ffffffffffff811681146111c957600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261122d57600080fd5b83018035915067ffffffffffffffff82111561124857600080fd5b60200191503681900382131561125d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60006020828403121561133857600080fd5b813561ffff811681146111c957600080fd5b60006020828403121561135c57600080fd5b813560ff811681146111c957600080fd5b60005b83811015611388578181015183820152602001611370565b50506000910152565b600081518084526113a981602086016020860161136d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c084015284518184015250602084015161014083015260408401516060610160840152611454610180840182611391565b905082810360e08401526114688185611391565b838103610100850152600081529050602081019b9a5050505050505050505050565b60006020828403121561149c57600080fd5b81516111c98161118a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156114f1576114f16114a7565b5092915050565b8082028115828204841417610b4b57610b4b6114a7565b600082611545577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561155c57600080fd5b815180151581146111c957600080fd5b6000825161157e81846020870161136d565b9190910192915050565b602081526000610b48602083018461139156fea26469706673582212208328d8149ca8eb632152123f06714fc50d6667b0823eba29b328ace315d4e37464736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/bsc/UniV2LikeFacet.json b/packages/hardhat/deployments/bsc/UniV2LikeFacet.json index c2ae9581..56e48343 100644 --- a/packages/hardhat/deployments/bsc/UniV2LikeFacet.json +++ b/packages/hardhat/deployments/bsc/UniV2LikeFacet.json @@ -1,5 +1,5 @@ { - "address": "0xd7f9d9b2245a09457BfbCAE5F39292596C1879E9", + "address": "0xb8B3A2C8D3062cae23AbB5A0B29D6DEE88167E70", "abi": [ { "inputs": [], @@ -116,6 +116,77 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV2LikeExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -193,7 +264,83 @@ "type": "tuple" } ], - "name": "uniswapV2LikeExactInput", + "name": "uniswapV2LikeExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV2LikeExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -286,7 +433,7 @@ "type": "tuple" } ], - "name": "uniswapV2LikeExactInputSingle", + "name": "uniswapV2LikeExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -294,32 +441,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0x17202a16597e488afd386467a58ff305340a26386ed3906e5e3cf3838aa8c742", + "transactionHash": "0x6d3c434b6132affff92e59a88628e37248962d334aef49cd1ce3865929363e8c", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xd7f9d9b2245a09457BfbCAE5F39292596C1879E9", - "transactionIndex": 90, - "gasUsed": "2101579", + "contractAddress": "0xb8B3A2C8D3062cae23AbB5A0B29D6DEE88167E70", + "transactionIndex": 74, + "gasUsed": "2340469", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x97d4ff9d4ea68d1cde7089682e3a16e49749404fec78324a39db3a69c59b8874", - "transactionHash": "0x17202a16597e488afd386467a58ff305340a26386ed3906e5e3cf3838aa8c742", + "blockHash": "0x7195be373ffd028460baaaf9588054798115ad097d4c2a13d68bd1abcd58dc9d", + "transactionHash": "0x6d3c434b6132affff92e59a88628e37248962d334aef49cd1ce3865929363e8c", "logs": [], - "blockNumber": 32736307, - "cumulativeGasUsed": "9214633", + "blockNumber": 33248451, + "cumulativeGasUsed": "8622578", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 5, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokens[0],\\n isToEth ? address(0) : params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x4d807156203d016fd7fe1ff2dd503972c0f07d9d8f1b0794aca4459c1ea03b7a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Like is ILibStarVault, ILibWarp {\\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\":\"0x80c9be72cf89c5673f0acfb44d672ae65e86062906042a31007a9737c9e1a3db\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612542806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611e34565b610066565b60405190815260200160405180910390f35b610041610061366004612036565b6109e7565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101949190612176565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb6121fd565b0497505061030189602001518a60a00151611569565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611599565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61222c565b6040518563ffffffff1660e01b81526004016104db9493929190612298565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b505050506101008a01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190612176565b90508481108061076b57506107688986612389565b81105b156107a2576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c48b60c001518c61010001518d6080015161ffff168e602001518d61162b565b985085156108f35787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108ad576040519150601f19603f3d011682016040523d82523d6000602084013e6108b2565b606091505b50509050806108ed576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610927565b6109278b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b85610937578a610100015161093a565b60005b73ffffffffffffffffffffffffffffffffffffffff168761095f578b60e00151610962565b60005b73ffffffffffffffffffffffffffffffffffffffff168c60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38e600001518d6040516109d1929190918252602082015260400190565b60405180910390a4505050505050505092915050565b60008260c0015165ffffffffffff16421115610a2f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1092916000918291908290610a7557610a7561239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610ac657610ac661239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610ba4578761010001518481518110610b0557610b0561239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9f9190612176565b610ba6565b475b90506000610bc889604001518a600001518b61010001518c61012001516116e4565b9050610bdc89602001518a60800151611569565b8160018351610beb91906123cb565b81518110610bfb57610bfb61239c565b60200260200101511015610c3b576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610d725788513414610c7b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b5050505050610d6d896101200151600081518110610d1b57610d1b61239c565b60200260200101518a600001518b6101000151600081518110610d4057610d4061239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b610fc7565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610de157610de161239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610e87919061222c565b6040518563ffffffff1660e01b8152600401610ea69493929190612298565b600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610f1557610f1561239c565b60200260200101518c600001518d6101000151600081518110610f3a57610f3a61239c565b60200260200101516040518563ffffffff1660e01b8152600401610f94949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610fae57600080fd5b505af1158015610fc2573d6000803e3d6000fd5b505050505b60005b858110156111d0576000610fdf826001612389565b905060008b61010001518281518110610ffa57610ffa61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c6101000151848151811061102f5761102f61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061105957600061105c565b60015b9050600060028d61010001515161107391906123cb565b841061107f573061109f565b8c610120015183815181106110965761109661239c565b60200260200101515b90508c610120015184815181106110b8576110b861239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836110ff578685815181106110f2576110f261239c565b6020026020010151611102565b60005b8461110e576000611129565b8786815181106111205761112061239c565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156111a957600080fd5b505af11580156111bd573d6000803e3d6000fd5b505060019095019450610fca9350505050565b50600089610100015186815181106111ea576111ea61239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190612176565b90508281108061129c57506112998884612389565b81105b156112d3576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113278a60e001518b610100015188815181106112f2576112f261239c565b60200260200101518c60a0015161ffff168d60200151868b8151811061131a5761131a61239c565b602002602001015161162b565b975083156114565786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611410576040519150601f19603f3d011682016040523d82523d6000602084013e611415565b606091505b5050905080611450576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611476565b6114768a60600151898c61010001518981518110610d4057610d4061239c565b8361149f5789610100015186815181106114925761149261239c565b60200260200101516114a2565b60005b73ffffffffffffffffffffffffffffffffffffffff16856114e2578a61010001516000815181106114d5576114d561239c565b60200260200101516114e5565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60e0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c604051611554929190918252602082015260400190565b60405180910390a45050505050505092915050565b600061271061157883826123de565b6115869061ffff1685612400565b6115909190612417565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611626908490611919565b505050565b60006107d0841115611672576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611684575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116ba57606460328402046116bd565b60005b90508083038382146116d5576116d58a8a8484611a28565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561170457611704611cff565b60405190808252806020026020018201604052801561172d578160200160208202803683370190505b50915084826000815181106117445761174461239c565b60200260200101818152505060005b8181101561190f57600085828151811061176f5761176f61239c565b602002602001015190506000868360016117899190612389565b815181106117995761179961239c565b6020026020010151905060008984815181106117b7576117b761239c565b60200260200101516127106117cc91906123de565b61ffff1690506000808886815181106117e7576117e761239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185d91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156118b857905b828b0282612710020181848d0202816118d3576118d36121fd565b049a508a886118e3886001612389565b815181106118f3576118f361239c565b6020908102919091010152505060019093019250611753915050565b5050949350505050565b600061197b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611af09092919063ffffffff16565b905080516000148061199c57508080602001905181019061199c9190612452565b611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611669565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611aff8484600085611b07565b949350505050565b606082471015611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611669565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bc2919061249f565b60006040518083038185875af1925050503d8060008114611bff576040519150601f19603f3d011682016040523d82523d6000602084013e611c04565b606091505b5091509150611c1587838387611c20565b979650505050505050565b60608315611cb6578251600003611caf5773ffffffffffffffffffffffffffffffffffffffff85163b611caf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611669565b5081611aff565b611aff8383815115611ccb5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166991906124bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611d5257611d52611cff565b60405290565b604051610140810167ffffffffffffffff81118282101715611d5257611d52611cff565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc357611dc3611cff565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611def57600080fd5b919050565b803561ffff81168114611def57600080fd5b803565ffffffffffff81168114611def57600080fd5b600060408284031215611e2e57600080fd5b50919050565b600080828403610180811215611e4957600080fd5b61016080821215611e5957600080fd5b611e61611d2e565b91508435825260208501356020830152611e7d60408601611dcb565b6040830152611e8e60608601611dcb565b6060830152611e9f60808601611df4565b6080830152611eb060a08601611df4565b60a0830152611ec160c08601611dcb565b60c0830152611ed260e08601611dcb565b60e0830152610100611ee5818701611dcb565b90830152610120611ef7868201611df4565b90830152610140611f09868201611e06565b9083015290925083013567ffffffffffffffff811115611f2857600080fd5b611f3485828601611e1c565b9150509250929050565b600067ffffffffffffffff821115611f5857611f58611cff565b5060051b60200190565b600082601f830112611f7357600080fd5b81356020611f88611f8383611f3e565b611d7c565b82815260059290921b84018101918181019086841115611fa757600080fd5b8286015b84811015611fc957611fbc81611df4565b8352918301918301611fab565b509695505050505050565b600082601f830112611fe557600080fd5b81356020611ff5611f8383611f3e565b82815260059290921b8401810191818101908684111561201457600080fd5b8286015b84811015611fc95761202981611dcb565b8352918301918301612018565b6000806040838503121561204957600080fd5b823567ffffffffffffffff8082111561206157600080fd5b90840190610140828703121561207657600080fd5b61207e611d58565b823581526020830135602082015260408301358281111561209e57600080fd5b6120aa88828601611f62565b6040830152506120bc60608401611dcb565b60608201526120cd60808401611df4565b60808201526120de60a08401611df4565b60a08201526120ef60c08401611e06565b60c082015261210060e08401611dcb565b60e0820152610100808401358381111561211957600080fd5b61212589828701611fd4565b828401525050610120808401358381111561213f57600080fd5b61214b89828701611fd4565b82840152505080945050602085013591508082111561216957600080fd5b50611f3485828601611e1c565b60006020828403121561218857600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611def57600080fd5b6000806000606084860312156121c257600080fd5b6121cb8461218f565b92506121d96020850161218f565b9150604084015163ffffffff811681146121f257600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261226157600080fd5b83018035915067ffffffffffffffff82111561227c57600080fd5b60200191503681900382131561229157600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156115935761159361235a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b818103818111156115935761159361235a565b61ffff8281168282160390808211156123f9576123f961235a565b5092915050565b80820281158282048414176115935761159361235a565b60008261244d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561246457600080fd5b8151801515811461247457600080fd5b9392505050565b60005b8381101561249657818101518382015260200161247e565b50506000910152565b600082516124b181846020870161247b565b9190910192915050565b60208152600082518060208401526124da81604085016020870161247b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220200d00eba2c244bcc4394586e11bed52f1bde27d737f84e6823312ec945bdf2064736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611e34565b610066565b60405190815260200160405180910390f35b610041610061366004612036565b6109e7565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101949190612176565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb6121fd565b0497505061030189602001518a60a00151611569565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611599565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61222c565b6040518563ffffffff1660e01b81526004016104db9493929190612298565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b505050506101008a01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190612176565b90508481108061076b57506107688986612389565b81105b156107a2576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c48b60c001518c61010001518d6080015161ffff168e602001518d61162b565b985085156108f35787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108ad576040519150601f19603f3d011682016040523d82523d6000602084013e6108b2565b606091505b50509050806108ed576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610927565b6109278b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b85610937578a610100015161093a565b60005b73ffffffffffffffffffffffffffffffffffffffff168761095f578b60e00151610962565b60005b73ffffffffffffffffffffffffffffffffffffffff168c60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38e600001518d6040516109d1929190918252602082015260400190565b60405180910390a4505050505050505092915050565b60008260c0015165ffffffffffff16421115610a2f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1092916000918291908290610a7557610a7561239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610ac657610ac661239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610ba4578761010001518481518110610b0557610b0561239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9f9190612176565b610ba6565b475b90506000610bc889604001518a600001518b61010001518c61012001516116e4565b9050610bdc89602001518a60800151611569565b8160018351610beb91906123cb565b81518110610bfb57610bfb61239c565b60200260200101511015610c3b576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610d725788513414610c7b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b5050505050610d6d896101200151600081518110610d1b57610d1b61239c565b60200260200101518a600001518b6101000151600081518110610d4057610d4061239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b610fc7565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610de157610de161239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610e87919061222c565b6040518563ffffffff1660e01b8152600401610ea69493929190612298565b600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610f1557610f1561239c565b60200260200101518c600001518d6101000151600081518110610f3a57610f3a61239c565b60200260200101516040518563ffffffff1660e01b8152600401610f94949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610fae57600080fd5b505af1158015610fc2573d6000803e3d6000fd5b505050505b60005b858110156111d0576000610fdf826001612389565b905060008b61010001518281518110610ffa57610ffa61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c6101000151848151811061102f5761102f61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061105957600061105c565b60015b9050600060028d61010001515161107391906123cb565b841061107f573061109f565b8c610120015183815181106110965761109661239c565b60200260200101515b90508c610120015184815181106110b8576110b861239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836110ff578685815181106110f2576110f261239c565b6020026020010151611102565b60005b8461110e576000611129565b8786815181106111205761112061239c565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156111a957600080fd5b505af11580156111bd573d6000803e3d6000fd5b505060019095019450610fca9350505050565b50600089610100015186815181106111ea576111ea61239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190612176565b90508281108061129c57506112998884612389565b81105b156112d3576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113278a60e001518b610100015188815181106112f2576112f261239c565b60200260200101518c60a0015161ffff168d60200151868b8151811061131a5761131a61239c565b602002602001015161162b565b975083156114565786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611410576040519150601f19603f3d011682016040523d82523d6000602084013e611415565b606091505b5050905080611450576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611476565b6114768a60600151898c61010001518981518110610d4057610d4061239c565b8361149f5789610100015186815181106114925761149261239c565b60200260200101516114a2565b60005b73ffffffffffffffffffffffffffffffffffffffff16856114e2578a61010001516000815181106114d5576114d561239c565b60200260200101516114e5565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60e0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c604051611554929190918252602082015260400190565b60405180910390a45050505050505092915050565b600061271061157883826123de565b6115869061ffff1685612400565b6115909190612417565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611626908490611919565b505050565b60006107d0841115611672576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611684575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116ba57606460328402046116bd565b60005b90508083038382146116d5576116d58a8a8484611a28565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561170457611704611cff565b60405190808252806020026020018201604052801561172d578160200160208202803683370190505b50915084826000815181106117445761174461239c565b60200260200101818152505060005b8181101561190f57600085828151811061176f5761176f61239c565b602002602001015190506000868360016117899190612389565b815181106117995761179961239c565b6020026020010151905060008984815181106117b7576117b761239c565b60200260200101516127106117cc91906123de565b61ffff1690506000808886815181106117e7576117e761239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185d91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156118b857905b828b0282612710020181848d0202816118d3576118d36121fd565b049a508a886118e3886001612389565b815181106118f3576118f361239c565b6020908102919091010152505060019093019250611753915050565b5050949350505050565b600061197b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611af09092919063ffffffff16565b905080516000148061199c57508080602001905181019061199c9190612452565b611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611669565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611aff8484600085611b07565b949350505050565b606082471015611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611669565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bc2919061249f565b60006040518083038185875af1925050503d8060008114611bff576040519150601f19603f3d011682016040523d82523d6000602084013e611c04565b606091505b5091509150611c1587838387611c20565b979650505050505050565b60608315611cb6578251600003611caf5773ffffffffffffffffffffffffffffffffffffffff85163b611caf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611669565b5081611aff565b611aff8383815115611ccb5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166991906124bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611d5257611d52611cff565b60405290565b604051610140810167ffffffffffffffff81118282101715611d5257611d52611cff565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc357611dc3611cff565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611def57600080fd5b919050565b803561ffff81168114611def57600080fd5b803565ffffffffffff81168114611def57600080fd5b600060408284031215611e2e57600080fd5b50919050565b600080828403610180811215611e4957600080fd5b61016080821215611e5957600080fd5b611e61611d2e565b91508435825260208501356020830152611e7d60408601611dcb565b6040830152611e8e60608601611dcb565b6060830152611e9f60808601611df4565b6080830152611eb060a08601611df4565b60a0830152611ec160c08601611dcb565b60c0830152611ed260e08601611dcb565b60e0830152610100611ee5818701611dcb565b90830152610120611ef7868201611df4565b90830152610140611f09868201611e06565b9083015290925083013567ffffffffffffffff811115611f2857600080fd5b611f3485828601611e1c565b9150509250929050565b600067ffffffffffffffff821115611f5857611f58611cff565b5060051b60200190565b600082601f830112611f7357600080fd5b81356020611f88611f8383611f3e565b611d7c565b82815260059290921b84018101918181019086841115611fa757600080fd5b8286015b84811015611fc957611fbc81611df4565b8352918301918301611fab565b509695505050505050565b600082601f830112611fe557600080fd5b81356020611ff5611f8383611f3e565b82815260059290921b8401810191818101908684111561201457600080fd5b8286015b84811015611fc95761202981611dcb565b8352918301918301612018565b6000806040838503121561204957600080fd5b823567ffffffffffffffff8082111561206157600080fd5b90840190610140828703121561207657600080fd5b61207e611d58565b823581526020830135602082015260408301358281111561209e57600080fd5b6120aa88828601611f62565b6040830152506120bc60608401611dcb565b60608201526120cd60808401611df4565b60808201526120de60a08401611df4565b60a08201526120ef60c08401611e06565b60c082015261210060e08401611dcb565b60e0820152610100808401358381111561211957600080fd5b61212589828701611fd4565b828401525050610120808401358381111561213f57600080fd5b61214b89828701611fd4565b82840152505080945050602085013591508082111561216957600080fd5b50611f3485828601611e1c565b60006020828403121561218857600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611def57600080fd5b6000806000606084860312156121c257600080fd5b6121cb8461218f565b92506121d96020850161218f565b9150604084015163ffffffff811681146121f257600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261226157600080fd5b83018035915067ffffffffffffffff82111561227c57600080fd5b60200191503681900382131561229157600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156115935761159361235a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b818103818111156115935761159361235a565b61ffff8281168282160390808211156123f9576123f961235a565b5092915050565b80820281158282048414176115935761159361235a565b60008261244d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561246457600080fd5b8151801515811461247457600080fd5b9392505050565b60005b8381101561249657818101518382015260200161247e565b50506000910152565b600082516124b181846020870161247b565b9190910192915050565b60208152600082518060208401526124da81604085016020870161247b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220200d00eba2c244bcc4394586e11bed52f1bde27d737f84e6823312ec945bdf2064736f6c63430008130033", + "numDeployments": 6, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"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\":\"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\":\"uniswapV2LikeExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"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\":\"uniswapV2LikeExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\\n * NOTE: The tokens must already have been moved to the first pool\\n */\\n function uniswapV2LikeExactInputSingleInternal(\\n ExactInputSingleParams memory params\\n ) internal returns (uint256 amountOut) {\\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\\n } else {\\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\\n }\\n\\n return uniswapV2LikeExactInputSingleInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 the pool\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n params.pool,\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n\\n return uniswapV2LikeExactInputSingleInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputInternal(\\n ExactInputParams calldata params\\n ) internal returns (uint256 amountOut) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n address[] memory tokens = params.tokens;\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = tokens[0] == address(0);\\n bool isToEth = tokens[poolLength] == address(0);\\n\\n if (isFromEth) {\\n tokens[0] = address(s.weth);\\n }\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : tokens[0],\\n isToEth ? address(0) : tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokens[0] == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\\n }\\n\\n return uniswapV2LikeExactInputInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\n // Permit tokens / set allowance\\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n\\n return uniswapV2LikeExactInputInternal(params);\\n }\\n}\\n\",\"keccak256\":\"0x2264d60e017f7ec8aa13691a2cabd116d785824587c832a5cb8dbaa5336599c1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Like is ILibStarVault, ILibWarp {\\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 ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInputSinglePermit(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInputPermit(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x61257f389c4a69c463baafad1a008ed2e9d68936a7e4a2cbe5a0cdc60df61e40\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b5061299a806100206000396000f3fe60806040526004361061003f5760003560e01c806311f1fdef14610044578063baa8ed3514610076578063c83ee48414610089578063d1b72bc41461009c575b600080fd5b34801561005057600080fd5b5061006461005f366004612268565b6100bc565b60405190815260200160405180910390f35b6100646100843660046122b9565b610319565b6100646100973660046122e9565b61052d565b3480156100a857600080fd5b506100646100b736600461231e565b610766565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610126906101008c01908c016123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161015d6101608b016101408c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161018f61016089016101408a016123d2565b65ffffffffffff1690526101a660208701876123ed565b6040518563ffffffff1660e01b81526004016101c59493929190612459565b600060405180830381600087803b1580156101df57600080fd5b505af11580156101f3573d6000803e3d6000fd5b5050505061021e7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c785163361024e60808701606088016123a1565b8635610261610100890160e08a016123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102df57600080fd5b505af11580156102f3573d6000803e3d6000fd5b505050506103108380360381019061030b91906125ad565b610a0c565b90505b92915050565b600061032d610160830161014084016123d2565b65ffffffffffff1642111561036e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610381610100840160e085016123a1565b73ffffffffffffffffffffffffffffffffffffffff16036104d657348235146103d6576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561046257600080fd5b505af1158015610476573d6000803e3d6000fd5b50505050506104d182606001602081019061049191906123a1565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff169084356110ca565b61051b565b61051b336104ea60808501606086016123a1565b84356104fd610100870160e088016123a1565b73ffffffffffffffffffffffffffffffffffffffff169291906111a3565b61031361030b368490038401846125ad565b600061053f60e0830160c084016123d2565b65ffffffffffff16421115610580576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610590610100840184612679565b60008181106105a1576105a16126e1565b90506020020160208101906105b691906123a1565b73ffffffffffffffffffffffffffffffffffffffff16036106ef573482351461060b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561069757600080fd5b505af11580156106ab573d6000803e3d6000fd5b50505050506106ea828061012001906106c49190612679565b60008181106106d5576106d56126e1565b905060200201602081019061049191906123a1565b61075d565b61075d33610701610120850185612679565b6000818110610712576107126126e1565b905060200201602081019061072791906123a1565b8435610737610100870187612679565b6000818110610748576107486126e1565b90506020020160208101906104fd91906123a1565b61031382611207565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915260009173ffffffffffffffffffffffffffffffffffffffff1690632b67b5709033908060608101806107c96101008b018b612679565b60008181106107da576107da6126e1565b90506020020160208101906107ef91906123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161082460e08b0160c08c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161085460e0890160c08a016123d2565b65ffffffffffff16905261086b60208701876123ed565b6040518563ffffffff1660e01b815260040161088a9493929190612459565b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506108e37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633610911610120870187612679565b6000818110610922576109226126e1565b905060200201602081019061093791906123a1565b8635610947610100890189612679565b6000818110610958576109586126e1565b905060200201602081019061096d91906123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050505061031083611207565b60e08101516101008201516000917f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff918216159116158381610af8576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af39190612710565b610afa565b475b90508215610b2057835473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8115610b4557835473ffffffffffffffffffffffffffffffffffffffff166101008701525b600080876060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915087610100015173ffffffffffffffffffffffffffffffffffffffff168860e0015173ffffffffffffffffffffffffffffffffffffffff161115610c1f57905b610120880151885161ffff6127109283031691840290820290810190830281610c4a57610c4a612797565b04975050610c6088602001518960a00151611b42565b871015610c99576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1610610cde576000610ce1565b60015b9050886060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610d0e5789610d11565b60005b83610d1d576000610d1f565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015610d8957600080fd5b505af1158015610d9d573d6000803e3d6000fd5b505050506101008901516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190612710565b905084811080610e4f5750610e4c89866127f5565b81105b15610e86576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea88a60c001518b61010001518c6080015161ffff168d602001518d611b69565b98508515610fd75787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d8060008114610f91576040519150601f19603f3d011682016040523d82523d6000602084013e610f96565b606091505b5050905080610fd1576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061100b565b61100b8a604001518a8c610100015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b8561101b5789610100015161101e565b60005b73ffffffffffffffffffffffffffffffffffffffff1687611043578a60e00151611046565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518d6040516110b5929190918252602082015260400190565b60405180910390a45050505050505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261119e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c22565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161111c565b50505050565b60007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1081611239610100850185612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061127b92505050610120860186612679565b9050905060008073ffffffffffffffffffffffffffffffffffffffff16836000815181106112ab576112ab6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168484815181106112f7576112f76126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115611387578454845173ffffffffffffffffffffffffffffffffffffffff90911690859060009061134c5761134c6126e1565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008161143f578484815181106113a0576113a06126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143a9190612710565b611441565b475b905060006114d061145560408b018b612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508c3591508990506114996101208e018e612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d3192505050565b90506114ef60208a01356114ea60a08c0160808d01612808565b611b42565b81600183516114fe9190612823565b8151811061150e5761150e6126e1565b6020026020010151101561154e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8581101561176f5760006115668260016127f5565b9050600088828151811061157c5761157c6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168984815181106115ac576115ac6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106115d65760006115d9565b60015b9050600060028a516115eb9190612823565b84106115f7573061162a565b6116056101208e018e612679565b84818110611615576116156126e1565b905060200201602081019061162a91906123a1565b905061163a6101208e018e612679565b8581811061164a5761164a6126e1565b905060200201602081019061165f91906123a1565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361169e57868581518110611691576116916126e1565b60200260200101516116a1565b60005b846116ad5760006116c8565b8786815181106116bf576116bf6126e1565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561174857600080fd5b505af115801561175c573d6000803e3d6000fd5b5050600190950194506115519350505050565b506000868681518110611784576117846126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190612710565b905082811080611836575061183389846127f5565b81105b1561186d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d66118816101008c0160e08d016123a1565b888881518110611893576118936126e1565b60200260200101518c60a00160208101906118ae9190612808565b61ffff168d60200135868b815181106118c9576118c96126e1565b6020026020010151611b69565b98508315611a125787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561194957600080fd5b505af115801561195d573d6000803e3d6000fd5b506000925061197591505060808c0160608d016123a1565b73ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146119cc576040519150601f19603f3d011682016040523d82523d6000602084013e6119d1565b606091505b5050905080611a0c576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611a65565b611a65611a2560808c0160608d016123a1565b8a898981518110611a3857611a386126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b83611a8957868681518110611a7c57611a7c6126e1565b6020026020010151611a8c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685611ac75787600081518110611aba57611aba6126e1565b6020026020010151611aca565b60005b73ffffffffffffffffffffffffffffffffffffffff16611af16101008d0160e08e016123a1565b604080518e358152602081018e905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f391016110b5565b6000612710611b518382612836565b611b5f9061ffff1685612858565b610310919061286f565b60006107d0841115611bb0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611bc2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611bf85760646032840204611bfb565b60005b9050808303838214611c1357611c138a8a8484611f66565b50505090910395945050505050565b6000611c84826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661202e9092919063ffffffff16565b9050805160001480611ca5575080806020019051810190611ca591906128aa565b61119e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611ba7565b805182516060919067ffffffffffffffff811115611d5157611d5161251b565b604051908082528060200260200182016040528015611d7a578160200160208202803683370190505b5091508482600081518110611d9157611d916126e1565b60200260200101818152505060005b81811015611f5c576000858281518110611dbc57611dbc6126e1565b60200260200101519050600086836001611dd691906127f5565b81518110611de657611de66126e1565b602002602001015190506000898481518110611e0457611e046126e1565b6020026020010151612710611e199190612836565b61ffff169050600080888681518110611e3457611e346126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115611f0557905b828b0282612710020181848d020281611f2057611f20612797565b049a508a88611f308860016127f5565b81518110611f4057611f406126e1565b6020908102919091010152505060019093019250611da0915050565b5050949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061203d8484600085612045565b949350505050565b6060824710156120d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611ba7565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161210091906128f7565b60006040518083038185875af1925050503d806000811461213d576040519150601f19603f3d011682016040523d82523d6000602084013e612142565b606091505b50915091506121538783838761215e565b979650505050505050565b606083156121f45782516000036121ed5773ffffffffffffffffffffffffffffffffffffffff85163b6121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611ba7565b508161203d565b61203d83838151156122095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79190612913565b6000610160828403121561225057600080fd5b50919050565b60006040828403121561225057600080fd5b600080610180838503121561227c57600080fd5b612286848461223d565b915061016083013567ffffffffffffffff8111156122a357600080fd5b6122af85828601612256565b9150509250929050565b600061016082840312156122cc57600080fd5b610310838361223d565b6000610140828403121561225057600080fd5b6000602082840312156122fb57600080fd5b813567ffffffffffffffff81111561231257600080fd5b61203d848285016122d6565b6000806040838503121561233157600080fd5b823567ffffffffffffffff8082111561234957600080fd5b612355868387016122d6565b9350602085013591508082111561236b57600080fd5b506122af85828601612256565b803573ffffffffffffffffffffffffffffffffffffffff8116811461239c57600080fd5b919050565b6000602082840312156123b357600080fd5b61031082612378565b803565ffffffffffff8116811461239c57600080fd5b6000602082840312156123e457600080fd5b610310826123bc565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261242257600080fd5b83018035915067ffffffffffffffff82111561243d57600080fd5b60200191503681900382131561245257600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715612595577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803561ffff8116811461239c57600080fd5b600061016082840312156125c057600080fd5b6125c861254a565b82358152602083013560208201526125e260408401612378565b60408201526125f360608401612378565b60608201526126046080840161259b565b608082015261261560a0840161259b565b60a082015261262660c08401612378565b60c082015261263760e08401612378565b60e082015261010061264a818501612378565b9082015261012061265c84820161259b565b9082015261014061266e8482016123bc565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126ae57600080fd5b83018035915067ffffffffffffffff8211156126c957600080fd5b6020019150600581901b360382131561245257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561272257600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461239c57600080fd5b60008060006060848603121561275c57600080fd5b61276584612729565b925061277360208501612729565b9150604084015163ffffffff8116811461278c57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610313576103136127c6565b60006020828403121561281a57600080fd5b6103108261259b565b81810381811115610313576103136127c6565b61ffff828116828216039080821115612851576128516127c6565b5092915050565b8082028115828204841417610313576103136127c6565b6000826128a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156128bc57600080fd5b815180151581146128cc57600080fd5b9392505050565b60005b838110156128ee5781810151838201526020016128d6565b50506000910152565b600082516129098184602087016128d3565b9190910192915050565b60208152600082518060208401526129328160408501602087016128d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de44c59485b64a44309171bd5ec5a3aa82d4e9417058be7ee66435ce87ad82ed64736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003f5760003560e01c806311f1fdef14610044578063baa8ed3514610076578063c83ee48414610089578063d1b72bc41461009c575b600080fd5b34801561005057600080fd5b5061006461005f366004612268565b6100bc565b60405190815260200160405180910390f35b6100646100843660046122b9565b610319565b6100646100973660046122e9565b61052d565b3480156100a857600080fd5b506100646100b736600461231e565b610766565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610126906101008c01908c016123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161015d6101608b016101408c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161018f61016089016101408a016123d2565b65ffffffffffff1690526101a660208701876123ed565b6040518563ffffffff1660e01b81526004016101c59493929190612459565b600060405180830381600087803b1580156101df57600080fd5b505af11580156101f3573d6000803e3d6000fd5b5050505061021e7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c785163361024e60808701606088016123a1565b8635610261610100890160e08a016123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102df57600080fd5b505af11580156102f3573d6000803e3d6000fd5b505050506103108380360381019061030b91906125ad565b610a0c565b90505b92915050565b600061032d610160830161014084016123d2565b65ffffffffffff1642111561036e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610381610100840160e085016123a1565b73ffffffffffffffffffffffffffffffffffffffff16036104d657348235146103d6576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561046257600080fd5b505af1158015610476573d6000803e3d6000fd5b50505050506104d182606001602081019061049191906123a1565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff169084356110ca565b61051b565b61051b336104ea60808501606086016123a1565b84356104fd610100870160e088016123a1565b73ffffffffffffffffffffffffffffffffffffffff169291906111a3565b61031361030b368490038401846125ad565b600061053f60e0830160c084016123d2565b65ffffffffffff16421115610580576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610590610100840184612679565b60008181106105a1576105a16126e1565b90506020020160208101906105b691906123a1565b73ffffffffffffffffffffffffffffffffffffffff16036106ef573482351461060b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561069757600080fd5b505af11580156106ab573d6000803e3d6000fd5b50505050506106ea828061012001906106c49190612679565b60008181106106d5576106d56126e1565b905060200201602081019061049191906123a1565b61075d565b61075d33610701610120850185612679565b6000818110610712576107126126e1565b905060200201602081019061072791906123a1565b8435610737610100870187612679565b6000818110610748576107486126e1565b90506020020160208101906104fd91906123a1565b61031382611207565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915260009173ffffffffffffffffffffffffffffffffffffffff1690632b67b5709033908060608101806107c96101008b018b612679565b60008181106107da576107da6126e1565b90506020020160208101906107ef91906123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161082460e08b0160c08c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161085460e0890160c08a016123d2565b65ffffffffffff16905261086b60208701876123ed565b6040518563ffffffff1660e01b815260040161088a9493929190612459565b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506108e37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633610911610120870187612679565b6000818110610922576109226126e1565b905060200201602081019061093791906123a1565b8635610947610100890189612679565b6000818110610958576109586126e1565b905060200201602081019061096d91906123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050505061031083611207565b60e08101516101008201516000917f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff918216159116158381610af8576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af39190612710565b610afa565b475b90508215610b2057835473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8115610b4557835473ffffffffffffffffffffffffffffffffffffffff166101008701525b600080876060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915087610100015173ffffffffffffffffffffffffffffffffffffffff168860e0015173ffffffffffffffffffffffffffffffffffffffff161115610c1f57905b610120880151885161ffff6127109283031691840290820290810190830281610c4a57610c4a612797565b04975050610c6088602001518960a00151611b42565b871015610c99576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1610610cde576000610ce1565b60015b9050886060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610d0e5789610d11565b60005b83610d1d576000610d1f565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015610d8957600080fd5b505af1158015610d9d573d6000803e3d6000fd5b505050506101008901516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190612710565b905084811080610e4f5750610e4c89866127f5565b81105b15610e86576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea88a60c001518b61010001518c6080015161ffff168d602001518d611b69565b98508515610fd75787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d8060008114610f91576040519150601f19603f3d011682016040523d82523d6000602084013e610f96565b606091505b5050905080610fd1576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061100b565b61100b8a604001518a8c610100015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b8561101b5789610100015161101e565b60005b73ffffffffffffffffffffffffffffffffffffffff1687611043578a60e00151611046565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518d6040516110b5929190918252602082015260400190565b60405180910390a45050505050505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261119e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c22565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161111c565b50505050565b60007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1081611239610100850185612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061127b92505050610120860186612679565b9050905060008073ffffffffffffffffffffffffffffffffffffffff16836000815181106112ab576112ab6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168484815181106112f7576112f76126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115611387578454845173ffffffffffffffffffffffffffffffffffffffff90911690859060009061134c5761134c6126e1565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008161143f578484815181106113a0576113a06126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143a9190612710565b611441565b475b905060006114d061145560408b018b612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508c3591508990506114996101208e018e612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d3192505050565b90506114ef60208a01356114ea60a08c0160808d01612808565b611b42565b81600183516114fe9190612823565b8151811061150e5761150e6126e1565b6020026020010151101561154e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8581101561176f5760006115668260016127f5565b9050600088828151811061157c5761157c6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168984815181106115ac576115ac6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106115d65760006115d9565b60015b9050600060028a516115eb9190612823565b84106115f7573061162a565b6116056101208e018e612679565b84818110611615576116156126e1565b905060200201602081019061162a91906123a1565b905061163a6101208e018e612679565b8581811061164a5761164a6126e1565b905060200201602081019061165f91906123a1565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361169e57868581518110611691576116916126e1565b60200260200101516116a1565b60005b846116ad5760006116c8565b8786815181106116bf576116bf6126e1565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561174857600080fd5b505af115801561175c573d6000803e3d6000fd5b5050600190950194506115519350505050565b506000868681518110611784576117846126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190612710565b905082811080611836575061183389846127f5565b81105b1561186d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d66118816101008c0160e08d016123a1565b888881518110611893576118936126e1565b60200260200101518c60a00160208101906118ae9190612808565b61ffff168d60200135868b815181106118c9576118c96126e1565b6020026020010151611b69565b98508315611a125787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561194957600080fd5b505af115801561195d573d6000803e3d6000fd5b506000925061197591505060808c0160608d016123a1565b73ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146119cc576040519150601f19603f3d011682016040523d82523d6000602084013e6119d1565b606091505b5050905080611a0c576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611a65565b611a65611a2560808c0160608d016123a1565b8a898981518110611a3857611a386126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b83611a8957868681518110611a7c57611a7c6126e1565b6020026020010151611a8c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685611ac75787600081518110611aba57611aba6126e1565b6020026020010151611aca565b60005b73ffffffffffffffffffffffffffffffffffffffff16611af16101008d0160e08e016123a1565b604080518e358152602081018e905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f391016110b5565b6000612710611b518382612836565b611b5f9061ffff1685612858565b610310919061286f565b60006107d0841115611bb0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611bc2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611bf85760646032840204611bfb565b60005b9050808303838214611c1357611c138a8a8484611f66565b50505090910395945050505050565b6000611c84826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661202e9092919063ffffffff16565b9050805160001480611ca5575080806020019051810190611ca591906128aa565b61119e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611ba7565b805182516060919067ffffffffffffffff811115611d5157611d5161251b565b604051908082528060200260200182016040528015611d7a578160200160208202803683370190505b5091508482600081518110611d9157611d916126e1565b60200260200101818152505060005b81811015611f5c576000858281518110611dbc57611dbc6126e1565b60200260200101519050600086836001611dd691906127f5565b81518110611de657611de66126e1565b602002602001015190506000898481518110611e0457611e046126e1565b6020026020010151612710611e199190612836565b61ffff169050600080888681518110611e3457611e346126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115611f0557905b828b0282612710020181848d020281611f2057611f20612797565b049a508a88611f308860016127f5565b81518110611f4057611f406126e1565b6020908102919091010152505060019093019250611da0915050565b5050949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061203d8484600085612045565b949350505050565b6060824710156120d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611ba7565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161210091906128f7565b60006040518083038185875af1925050503d806000811461213d576040519150601f19603f3d011682016040523d82523d6000602084013e612142565b606091505b50915091506121538783838761215e565b979650505050505050565b606083156121f45782516000036121ed5773ffffffffffffffffffffffffffffffffffffffff85163b6121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611ba7565b508161203d565b61203d83838151156122095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79190612913565b6000610160828403121561225057600080fd5b50919050565b60006040828403121561225057600080fd5b600080610180838503121561227c57600080fd5b612286848461223d565b915061016083013567ffffffffffffffff8111156122a357600080fd5b6122af85828601612256565b9150509250929050565b600061016082840312156122cc57600080fd5b610310838361223d565b6000610140828403121561225057600080fd5b6000602082840312156122fb57600080fd5b813567ffffffffffffffff81111561231257600080fd5b61203d848285016122d6565b6000806040838503121561233157600080fd5b823567ffffffffffffffff8082111561234957600080fd5b612355868387016122d6565b9350602085013591508082111561236b57600080fd5b506122af85828601612256565b803573ffffffffffffffffffffffffffffffffffffffff8116811461239c57600080fd5b919050565b6000602082840312156123b357600080fd5b61031082612378565b803565ffffffffffff8116811461239c57600080fd5b6000602082840312156123e457600080fd5b610310826123bc565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261242257600080fd5b83018035915067ffffffffffffffff82111561243d57600080fd5b60200191503681900382131561245257600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715612595577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803561ffff8116811461239c57600080fd5b600061016082840312156125c057600080fd5b6125c861254a565b82358152602083013560208201526125e260408401612378565b60408201526125f360608401612378565b60608201526126046080840161259b565b608082015261261560a0840161259b565b60a082015261262660c08401612378565b60c082015261263760e08401612378565b60e082015261010061264a818501612378565b9082015261012061265c84820161259b565b9082015261014061266e8482016123bc565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126ae57600080fd5b83018035915067ffffffffffffffff8211156126c957600080fd5b6020019150600581901b360382131561245257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561272257600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461239c57600080fd5b60008060006060848603121561275c57600080fd5b61276584612729565b925061277360208501612729565b9150604084015163ffffffff8116811461278c57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610313576103136127c6565b60006020828403121561281a57600080fd5b6103108261259b565b81810381811115610313576103136127c6565b61ffff828116828216039080821115612851576128516127c6565b5092915050565b8082028115828204841417610313576103136127c6565b6000826128a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156128bc57600080fd5b815180151581146128cc57600080fd5b9392505050565b60005b838110156128ee5781810151838201526020016128d6565b50506000910152565b600082516129098184602087016128d3565b9190910192915050565b60208152600082518060208401526129328160408501602087016128d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de44c59485b64a44309171bd5ec5a3aa82d4e9417058be7ee66435ce87ad82ed64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/bsc/UniV3Callback.json b/packages/hardhat/deployments/bsc/UniV3Callback.json index f1c38e1e..e7037dbe 100644 --- a/packages/hardhat/deployments/bsc/UniV3Callback.json +++ b/packages/hardhat/deployments/bsc/UniV3Callback.json @@ -1,5 +1,5 @@ { - "address": "0x12Ad749fbdCF48bBc2D4aDcD00f95BA99bd13b63", + "address": "0x6Eb7651D827818B2dfdbA80E1A33743dEc3Fc701", "abi": [ { "inputs": [], @@ -122,28 +122,28 @@ "type": "function" } ], - "transactionHash": "0x8cd5e7ecb392d626ad413aae63470660914bee18543b853e05f0c293f45edca6", + "transactionHash": "0x5b1840ff95bf6dc77e18a7110c32ff8372ab27b12688962f21b1d17b15e60afb", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x12Ad749fbdCF48bBc2D4aDcD00f95BA99bd13b63", - "transactionIndex": 48, - "gasUsed": "490767", + "contractAddress": "0x6Eb7651D827818B2dfdbA80E1A33743dEc3Fc701", + "transactionIndex": 104, + "gasUsed": "548027", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x592a2b41972fadf602df2ccd63c898d26203c47bdcc4486924c221c6dcacd2ab", - "transactionHash": "0x8cd5e7ecb392d626ad413aae63470660914bee18543b853e05f0c293f45edca6", + "blockHash": "0x5f18ec075fda72c19a6844fdccf6e7947b11e7c01e0c20c84476deed43f82dee", + "transactionHash": "0x5b1840ff95bf6dc77e18a7110c32ff8372ab27b12688962f21b1d17b15e60afb", "logs": [], - "blockNumber": 32705915, - "cumulativeGasUsed": "7079052", + "blockNumber": 33248473, + "cumulativeGasUsed": "12239530", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "4a9aead708515414ed961374f1d066ed", - "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\":\"pancakeV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"ramsesV2SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swapCallback\",\"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\"},\"pancakeV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"ramsesV2SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"swapCallback(int256,int256,bytes)\":{\"notice\":\"KyperSwap V2 callback 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 /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * KyperSwap V2 callback\\n * NOTE: None of these arguments can be trusted\\n */\\n function swapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x85ecd0df604a102bbc22cbcfd07afec90fd4abb25b8fac2ce0bda48ba5663f82\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107f7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610687565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d5490911692820192909252903090036101c057805160408201516101bb9173ffffffffffffffffffffffffffffffffffffffff9091169033906102d2565b610288565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561026f57600080fd5b505af1158015610283573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261035f908490610364565b505050565b60006103c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104789092919063ffffffff16565b90508051600014806103e75750808060200190518101906103e79190610707565b61035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610487848460008561048f565b949350505050565b606082471015610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046f565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161054a9190610754565b60006040518083038185875af1925050503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d878383876105a8565b979650505050505050565b6060831561063e5782516000036106375773ffffffffffffffffffffffffffffffffffffffff85163b610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046f565b5081610487565b61048783838151156106535781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046f9190610770565b6000806000806060858703121561069d57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156106c357600080fd5b818701915087601f8301126106d757600080fd5b8135818111156106e657600080fd5b8860208285010111156106f857600080fd5b95989497505060200194505050565b60006020828403121561071957600080fd5b8151801515811461072957600080fd5b9392505050565b60005b8381101561074b578181015183820152602001610733565b50506000910152565b60008251610766818460208701610730565b9190910192915050565b602081526000825180602084015261078f816040850160208701610730565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e0c3a5ea77a59d4a136519a3fb790277ee65b84323dca008c9268c0208c1cb4364736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610687565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d5490911692820192909252903090036101c057805160408201516101bb9173ffffffffffffffffffffffffffffffffffffffff9091169033906102d2565b610288565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561026f57600080fd5b505af1158015610283573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261035f908490610364565b505050565b60006103c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104789092919063ffffffff16565b90508051600014806103e75750808060200190518101906103e79190610707565b61035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610487848460008561048f565b949350505050565b606082471015610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046f565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161054a9190610754565b60006040518083038185875af1925050503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d878383876105a8565b979650505050505050565b6060831561063e5782516000036106375773ffffffffffffffffffffffffffffffffffffffff85163b610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046f565b5081610487565b61048783838151156106535781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046f9190610770565b6000806000806060858703121561069d57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156106c357600080fd5b818701915087601f8301126106d757600080fd5b8135818111156106e657600080fd5b8860208285010111156106f857600080fd5b95989497505060200194505050565b60006020828403121561071957600080fd5b8151801515811461072957600080fd5b9392505050565b60005b8381101561074b578181015183820152602001610733565b50506000910152565b60008251610766818460208701610730565b9190910192915050565b602081526000825180602084015261078f816040850160208701610730565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e0c3a5ea77a59d4a136519a3fb790277ee65b84323dca008c9268c0208c1cb4364736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "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\":\"pancakeV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"ramsesV2SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swapCallback\",\"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\"},\"pancakeV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"ramsesV2SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"swapCallback(int256,int256,bytes)\":{\"notice\":\"KyperSwap V2 callback 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 if (callback.usePermit == 1) {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n } else {\\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\\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 /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * KyperSwap V2 callback\\n * NOTE: None of these arguments can be trusted\\n */\\n function swapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xe3eb6dae32a233cc02e3aa833b2a7bac774a3c9c2c11f6d8feae8745d976f4b6\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610903806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610793565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e546060820152903090036101e757805160408201516101e29173ffffffffffffffffffffffffffffffffffffffff909116903390610339565b6102ef565b80606001516001036102bf577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156102a257600080fd5b505af11580156102b6573d6000803e3d6000fd5b505050506102ef565b6020810151815160408301516102ef9273ffffffffffffffffffffffffffffffffffffffff909116913390610412565b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261040d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610470565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526100899085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161038b565b60006104d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166105849092919063ffffffff16565b90508051600014806104f35750808060200190518101906104f39190610813565b61040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610593848460008561059b565b949350505050565b60608247101561062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161057b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106569190610860565b60006040518083038185875af1925050503d8060008114610693576040519150601f19603f3d011682016040523d82523d6000602084013e610698565b606091505b50915091506106a9878383876106b4565b979650505050505050565b6060831561074a5782516000036107435773ffffffffffffffffffffffffffffffffffffffff85163b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057b565b5081610593565b610593838381511561075f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b919061087c565b600080600080606085870312156107a957600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156107cf57600080fd5b818701915087601f8301126107e357600080fd5b8135818111156107f257600080fd5b88602082850101111561080457600080fd5b95989497505060200194505050565b60006020828403121561082557600080fd5b8151801515811461083557600080fd5b9392505050565b60005b8381101561085757818101518382015260200161083f565b50506000910152565b6000825161087281846020870161083c565b9190910192915050565b602081526000825180602084015261089b81604085016020870161083c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bd61054b7d7be6361f4cde7d339ff2b4e90fc18022d2e43caaa86ef48c70f7df64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610793565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e546060820152903090036101e757805160408201516101e29173ffffffffffffffffffffffffffffffffffffffff909116903390610339565b6102ef565b80606001516001036102bf577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156102a257600080fd5b505af11580156102b6573d6000803e3d6000fd5b505050506102ef565b6020810151815160408301516102ef9273ffffffffffffffffffffffffffffffffffffffff909116913390610412565b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261040d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610470565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526100899085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161038b565b60006104d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166105849092919063ffffffff16565b90508051600014806104f35750808060200190518101906104f39190610813565b61040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610593848460008561059b565b949350505050565b60608247101561062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161057b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106569190610860565b60006040518083038185875af1925050503d8060008114610693576040519150601f19603f3d011682016040523d82523d6000602084013e610698565b606091505b50915091506106a9878383876106b4565b979650505050505050565b6060831561074a5782516000036107435773ffffffffffffffffffffffffffffffffffffffff85163b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057b565b5081610593565b610593838381511561075f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b919061087c565b600080600080606085870312156107a957600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156107cf57600080fd5b818701915087601f8301126107e357600080fd5b8135818111156107f257600080fd5b88602082850101111561080457600080fd5b95989497505060200194505050565b60006020828403121561082557600080fd5b8151801515811461083557600080fd5b9392505050565b60005b8381101561085757818101518382015260200161083f565b50506000910152565b6000825161087281846020870161083c565b9190910192915050565b602081526000825180602084015261089b81604085016020870161083c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bd61054b7d7be6361f4cde7d339ff2b4e90fc18022d2e43caaa86ef48c70f7df64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/bsc/UniV3Like.json b/packages/hardhat/deployments/bsc/UniV3Like.json index 66a1756e..87344dfa 100644 --- a/packages/hardhat/deployments/bsc/UniV3Like.json +++ b/packages/hardhat/deployments/bsc/UniV3Like.json @@ -1,5 +1,5 @@ { - "address": "0x71e0BD402c5C0B61dE1D224824c551fE0D623065", + "address": "0x1B1a2071353424d10A33fF3D6F9AC686c8B8dC20", "abi": [ { "inputs": [], @@ -136,6 +136,72 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV3LikeExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -208,7 +274,78 @@ "type": "tuple" } ], - "name": "uniswapV3LikeExactInput", + "name": "uniswapV3LikeExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV3LikeExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -296,7 +433,7 @@ "type": "tuple" } ], - "name": "uniswapV3LikeExactInputSingle", + "name": "uniswapV3LikeExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -304,32 +441,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0x80d95cc805d6e6ebe68d5eefd6a921147744321f274ce9009e439de7bc141ea7", + "transactionHash": "0x3e24ac0a9903e908a6d55aca1bf7f5000cb92209c234d1b62e0381c6ecc97db5", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x71e0BD402c5C0B61dE1D224824c551fE0D623065", - "transactionIndex": 125, - "gasUsed": "2039103", + "contractAddress": "0x1B1a2071353424d10A33fF3D6F9AC686c8B8dC20", + "transactionIndex": 123, + "gasUsed": "2135647", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x9bf0ff54465f06161f6349434e96f40864c86e32455531c4c3be815bc33f92b5", - "transactionHash": "0x80d95cc805d6e6ebe68d5eefd6a921147744321f274ce9009e439de7bc141ea7", + "blockHash": "0x8729b98a521a4daa05056d413ddf6b895a702e3dadea243be7cf05fae61b1c2f", + "transactionHash": "0x3e24ac0a9903e908a6d55aca1bf7f5000cb92209c234d1b62e0381c6ecc97db5", "logs": [], - "blockNumber": 32736419, - "cumulativeGasUsed": "18022253", + "blockNumber": 33248478, + "cumulativeGasUsed": "13982794", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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/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 {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokens[0],\\n isToEth ? address(0) : params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0778264b402de681401a9d1ca9ee9e1d313e2075b7d853b1504704a605ba6c23\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\\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\":\"0x61677478daa5f86ad18959bbe4a13b95a997853f844642be3f6eb54d6ab9a772\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612421806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611de2565b610066565b60405190815260200160405180910390f35b610041610061366004611f8f565b6109f6565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029291906120a9565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff1681525089806020019061045191906120c2565b6040518563ffffffff1660e01b8152600401610470949392919061212e565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e91906121f0565b9150508061057b90612243565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906121f0565b50905061066381612243565b9550505b61066f61173b565b610682876101000151886060015161179b565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906120a9565b9050828110806107685750610765868461227b565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c188602001518960e001518a6040015161ffff168b61010001518a6117cb565b95508315610910577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108ca576040519150601f19603f3d011682016040523d82523d6000602084013e6108cf565b606091505b505090508061090a576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061093a565b875160e089015161093a9173ffffffffffffffffffffffffffffffffffffffff9091169088611884565b83610949578760e0015161094c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685610971578860c00151610974565b60005b73ffffffffffffffffffffffffffffffffffffffff16896020015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38b608001518a6040516109e3929190918252602082015260400190565b60405180910390a4505050505092915050565b60008260a0015165ffffffffffff16421115610a3e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e0840151805160009182918290610a5f57610a5f61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e001518481518110610aaf57610aaf61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610add5733610adf565b305b90508215610bfd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610b3b57610b3b61228e565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610b9a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b5050505050505b8115610c90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610c5557610c5561228e565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610ca857610ca861228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906120a9565b88519650905083610ed3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610ddb57610ddb61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610e8191906120c2565b6040518563ffffffff1660e01b8152600401610ea0949392919061212e565b600060405180830381600087803b158015610eba57600080fd5b505af1158015610ece573d6000803e3d6000fd5b505050505b60005b858110156111c457600081600101905060008a60e001518281518110610efe57610efe61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610f3257610f3261228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610fbf60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610f9957610f9961228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b80156110b65760008b61010001518481518110610fde57610fde61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a191906121f0565b915050806110ae90612243565b9950506111b1565b60008b610100015184815181106110cf576110cf61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906121f0565b5090506111ad81612243565b9950505b6111b961173b565b503093509050610ed6565b506111d386896060015161179b565b86101561120c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e0015186815181106112245761122461228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561129a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112be91906120a9565b9050818110806112d657506112d3878361227b565b81105b1561130d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113478960c001518a60e00151888151811061132b5761132b61228e565b60200260200101518b6080015161ffff168c602001518b6117cb565b96508315611496577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156113da57600080fd5b505af11580156113ee573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611450576040519150601f19603f3d011682016040523d82523d6000602084013e611455565b606091505b5050905080611490576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506114e2565b6114e28960400151888b60e0015189815181106114b5576114b561228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166118849092919063ffffffff16565b8361150a578860e0015186815181106114fd576114fd61228e565b602002602001015161150d565b60005b73ffffffffffffffffffffffffffffffffffffffff168561154c578960e0015160008151811061153f5761153f61228e565b602002602001015161154f565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b6040516115be929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611630576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611799576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60006127106117aa83826122bd565b6117b89061ffff16856122df565b6117c291906122f6565b90505b92915050565b60006107d0841115611812576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611824575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561185a576064603284020461185d565b60005b9050808303838214611875576118758a8a8484611916565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526119119084906119de565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611a40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611aed9092919063ffffffff16565b9050805160001480611a61575080806020019051810190611a619190612331565b611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611809565b6060611afc8484600085611b04565b949350505050565b606082471015611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611809565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbf919061237e565b60006040518083038185875af1925050503d8060008114611bfc576040519150601f19603f3d011682016040523d82523d6000602084013e611c01565b606091505b5091509150611c1287838387611c1d565b979650505050505050565b60608315611cb3578251600003611cac5773ffffffffffffffffffffffffffffffffffffffff85163b611cac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611809565b5081611afc565b611afc8383815115611cc85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611809919061239a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b60405290565b604051610120810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d9d57600080fd5b919050565b803561ffff81168114611d9d57600080fd5b803565ffffffffffff81168114611d9d57600080fd5b600060408284031215611ddc57600080fd5b50919050565b600080828403610160811215611df757600080fd5b61014080821215611e0757600080fd5b611e0f611d2b565b9150611e1a85611d79565b8252611e2860208601611d79565b6020830152611e3960408601611da2565b6040830152611e4a60608601611da2565b606083015260808501356080830152611e6560a08601611db4565b60a0830152611e7660c08601611d79565b60c0830152611e8760e08601611d79565b60e08301526101008581013590830152610120611ea5818701611d79565b9083015290925083013567ffffffffffffffff811115611ec457600080fd5b611ed085828601611dca565b9150509250929050565b600082601f830112611eeb57600080fd5b8135602067ffffffffffffffff80831115611f0857611f08611cfc565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611f4b57611f4b611cfc565b604052938452858101830193838101925087851115611f6957600080fd5b83870191505b84821015611c1257611f8082611d79565b83529183019190830190611f6f565b60008060408385031215611fa257600080fd5b823567ffffffffffffffff80821115611fba57600080fd5b908401906101208287031215611fcf57600080fd5b611fd7611d55565b8235815260208301356020820152611ff160408401611d79565b604082015261200260608401611da2565b606082015261201360808401611da2565b608082015261202460a08401611db4565b60a082015261203560c08401611d79565b60c082015260e08301358281111561204c57600080fd5b61205888828601611eda565b60e083015250610100808401358381111561207257600080fd5b61207e89828701611eda565b82840152505080945050602085013591508082111561209c57600080fd5b50611ed085828601611dca565b6000602082840312156120bb57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120f757600080fd5b83018035915067ffffffffffffffff82111561211257600080fd5b60200191503681900382131561212757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561220357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361227457612274612214565b5060000390565b808201808211156117c5576117c5612214565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156122d8576122d8612214565b5092915050565b80820281158282048414176117c5576117c5612214565b60008261232c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561234357600080fd5b8151801515811461235357600080fd5b9392505050565b60005b8381101561237557818101518382015260200161235d565b50506000910152565b6000825161239081846020870161235a565b9190910192915050565b60208152600082518060208401526123b981604085016020870161235a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220576050a04e57b56eff16cf6c316bc8966ab4a176dcea2edf74c13dd26adc111164736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611de2565b610066565b60405190815260200160405180910390f35b610041610061366004611f8f565b6109f6565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029291906120a9565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff1681525089806020019061045191906120c2565b6040518563ffffffff1660e01b8152600401610470949392919061212e565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e91906121f0565b9150508061057b90612243565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906121f0565b50905061066381612243565b9550505b61066f61173b565b610682876101000151886060015161179b565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906120a9565b9050828110806107685750610765868461227b565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c188602001518960e001518a6040015161ffff168b61010001518a6117cb565b95508315610910577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108ca576040519150601f19603f3d011682016040523d82523d6000602084013e6108cf565b606091505b505090508061090a576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061093a565b875160e089015161093a9173ffffffffffffffffffffffffffffffffffffffff9091169088611884565b83610949578760e0015161094c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685610971578860c00151610974565b60005b73ffffffffffffffffffffffffffffffffffffffff16896020015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38b608001518a6040516109e3929190918252602082015260400190565b60405180910390a4505050505092915050565b60008260a0015165ffffffffffff16421115610a3e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e0840151805160009182918290610a5f57610a5f61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e001518481518110610aaf57610aaf61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610add5733610adf565b305b90508215610bfd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610b3b57610b3b61228e565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610b9a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b5050505050505b8115610c90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610c5557610c5561228e565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610ca857610ca861228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906120a9565b88519650905083610ed3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610ddb57610ddb61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610e8191906120c2565b6040518563ffffffff1660e01b8152600401610ea0949392919061212e565b600060405180830381600087803b158015610eba57600080fd5b505af1158015610ece573d6000803e3d6000fd5b505050505b60005b858110156111c457600081600101905060008a60e001518281518110610efe57610efe61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610f3257610f3261228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610fbf60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610f9957610f9961228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b80156110b65760008b61010001518481518110610fde57610fde61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a191906121f0565b915050806110ae90612243565b9950506111b1565b60008b610100015184815181106110cf576110cf61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906121f0565b5090506111ad81612243565b9950505b6111b961173b565b503093509050610ed6565b506111d386896060015161179b565b86101561120c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e0015186815181106112245761122461228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561129a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112be91906120a9565b9050818110806112d657506112d3878361227b565b81105b1561130d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113478960c001518a60e00151888151811061132b5761132b61228e565b60200260200101518b6080015161ffff168c602001518b6117cb565b96508315611496577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156113da57600080fd5b505af11580156113ee573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611450576040519150601f19603f3d011682016040523d82523d6000602084013e611455565b606091505b5050905080611490576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506114e2565b6114e28960400151888b60e0015189815181106114b5576114b561228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166118849092919063ffffffff16565b8361150a578860e0015186815181106114fd576114fd61228e565b602002602001015161150d565b60005b73ffffffffffffffffffffffffffffffffffffffff168561154c578960e0015160008151811061153f5761153f61228e565b602002602001015161154f565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b6040516115be929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611630576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611799576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60006127106117aa83826122bd565b6117b89061ffff16856122df565b6117c291906122f6565b90505b92915050565b60006107d0841115611812576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611824575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561185a576064603284020461185d565b60005b9050808303838214611875576118758a8a8484611916565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526119119084906119de565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611a40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611aed9092919063ffffffff16565b9050805160001480611a61575080806020019051810190611a619190612331565b611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611809565b6060611afc8484600085611b04565b949350505050565b606082471015611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611809565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbf919061237e565b60006040518083038185875af1925050503d8060008114611bfc576040519150601f19603f3d011682016040523d82523d6000602084013e611c01565b606091505b5091509150611c1287838387611c1d565b979650505050505050565b60608315611cb3578251600003611cac5773ffffffffffffffffffffffffffffffffffffffff85163b611cac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611809565b5081611afc565b611afc8383815115611cc85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611809919061239a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b60405290565b604051610120810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d9d57600080fd5b919050565b803561ffff81168114611d9d57600080fd5b803565ffffffffffff81168114611d9d57600080fd5b600060408284031215611ddc57600080fd5b50919050565b600080828403610160811215611df757600080fd5b61014080821215611e0757600080fd5b611e0f611d2b565b9150611e1a85611d79565b8252611e2860208601611d79565b6020830152611e3960408601611da2565b6040830152611e4a60608601611da2565b606083015260808501356080830152611e6560a08601611db4565b60a0830152611e7660c08601611d79565b60c0830152611e8760e08601611d79565b60e08301526101008581013590830152610120611ea5818701611d79565b9083015290925083013567ffffffffffffffff811115611ec457600080fd5b611ed085828601611dca565b9150509250929050565b600082601f830112611eeb57600080fd5b8135602067ffffffffffffffff80831115611f0857611f08611cfc565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611f4b57611f4b611cfc565b604052938452858101830193838101925087851115611f6957600080fd5b83870191505b84821015611c1257611f8082611d79565b83529183019190830190611f6f565b60008060408385031215611fa257600080fd5b823567ffffffffffffffff80821115611fba57600080fd5b908401906101208287031215611fcf57600080fd5b611fd7611d55565b8235815260208301356020820152611ff160408401611d79565b604082015261200260608401611da2565b606082015261201360808401611da2565b608082015261202460a08401611db4565b60a082015261203560c08401611d79565b60c082015260e08301358281111561204c57600080fd5b61205888828601611eda565b60e083015250610100808401358381111561207257600080fd5b61207e89828701611eda565b82840152505080945050602085013591508082111561209c57600080fd5b50611ed085828601611dca565b6000602082840312156120bb57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120f757600080fd5b83018035915067ffffffffffffffff82111561211257600080fd5b60200191503681900382131561212757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561220357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361227457612274612214565b5060000390565b808201808211156117c5576117c5612214565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156122d8576122d8612214565b5092915050565b80820281158282048414176117c5576117c5612214565b60008261232c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561234357600080fd5b8151801515811461235357600080fd5b9392505050565b60005b8381101561237557818101518382015260200161235d565b50506000910152565b6000825161239081846020870161235a565b9190910192915050565b60208152600082518060208401526123b981604085016020870161235a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220576050a04e57b56eff16cf6c316bc8966ab4a176dcea2edf74c13dd26adc111164736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"name\":\"uniswapV3LikeExactInput\",\"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\":\"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\":\"uniswapV3LikeExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"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\":\"uniswapV3LikeExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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/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 {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\\n ExactInputSingleParams calldata params,\\n uint256 usePermit\\n ) internal returns (uint256 amountOut) {\\n bool isFromEth = params.tokenIn == address(0);\\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\\n\\n address tokenOut = params.tokenOut == address(0)\\n ? address(LibWarp.state().weth)\\n : params.tokenOut;\\n\\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = tokenIn < tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: tokenIn,\\n amount: params.amountIn,\\n usePermit: usePermit\\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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (params.tokenOut == address(0)) {\\n // To ETH, unwrap WETH\\n // TODO: This is read twice. Compare gas usage\\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(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn == address(0)) {\\n // From ETH, wrap it\\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\\n }\\n\\n function uniswapV3LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\\n }\\n\\n function uniswapV3LikeExactInputInternal(\\n ExactInputParams calldata params,\\n uint256 usePermit\\n ) internal returns (uint256 amountOut) {\\n uint256 poolLength = params.pools.length;\\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\\n address[] memory tokens = params.tokens;\\n\\n if (params.tokens[0] == address(0)) {\\n tokens[0] = address(LibWarp.state().weth);\\n }\\n\\n if (params.tokens[poolLength] == address(0)) {\\n tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: payer,\\n token: tokens[index],\\n amount: amountOut,\\n usePermit: usePermit\\n })\\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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (params.tokens[poolLength] == address(0)) {\\n // To ETH, unwrap\\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n params.tokens[0],\\n params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokens[0] == address(0)) {\\n // From ETH, wrap it\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n }\\n\\n return uniswapV3LikeExactInputInternal(params, 0);\\n }\\n\\n function uniswapV3LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 return uniswapV3LikeExactInputInternal(params, 1);\\n }\\n}\\n\",\"keccak256\":\"0x9e23653ffdee1ddba14b812d0ed30da1b28d009e139fef4562407e722f5c541f\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\\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 calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x1fbea0694f83750cccdc1e2e316bc7466e7d04e7342fd7d4359459f056d30a71\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506125e1806100206000396000f3fe60806040526004361061003e5760003560e01c80626ee8b6146100435780635576abd114610068578063a33aea141461007b578063cda932d11461009b575b600080fd5b610056610051366004612064565b6100bb565b60405190815260200160405180910390f35b6100566100763660046120ac565b61024f565b34801561008757600080fd5b506100566100963660046120db565b6103b2565b3480156100a757600080fd5b506100566100b636600461212c565b6104fc565b60006100cd60c0830160a08401612186565b65ffffffffffff1642111561010e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061011d60e08401846121ae565b600081811061012e5761012e61221d565b9050602002016020810190610143919061224c565b73ffffffffffffffffffffffffffffffffffffffff160361023e5734823514610198576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b50505050505b61024982600061065b565b92915050565b600061026160c0830160a08401612186565b65ffffffffffff164211156102a2576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b460e0840160c0850161224c565b73ffffffffffffffffffffffffffffffffffffffff16036103a7577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660808301353414610344576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561038c57600080fd5b505af11580156103a0573d6000803e3d6000fd5b5050505050505b610249826000611118565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b57091339181906060820190819061041a908b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff908116825260808b013516602082015260400161045260c08b0160a08c01612186565b65ffffffffffff9081168252893516602091820152908252309082015260400161048260c0890160a08a01612186565b65ffffffffffff1690526104996020870187612282565b6040518563ffffffff1660e01b81526004016104b894939291906122e7565b600060405180830381600087803b1580156104d257600080fd5b505af11580156104e6573d6000803e3d6000fd5b505050506104f5836001611118565b9392505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610561908b018b6121ae565b60008181106105725761057261221d565b9050602002016020810190610587919061224c565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016105bc60c08b0160a08c01612186565b65ffffffffffff908116825289351660209182015290825230908201526040016105ec60c0890160a08a01612186565b65ffffffffffff1690526106036020870187612282565b6040518563ffffffff1660e01b815260040161062294939291906122e7565b600060405180830381600087803b15801561063c57600080fd5b505af1158015610650573d6000803e3d6000fd5b505050506104f58360015b60008061066c6101008501856121ae565b9150600090508061068060e08701876121ae565b60008181106106915761069161221d565b90506020020160208101906106a6919061224c565b73ffffffffffffffffffffffffffffffffffffffff16146106c757336106c9565b305b905060006106da60e08701876121ae565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061071b9250505060e08801886121ae565b600081811061072c5761072c61221d565b9050602002016020810190610741919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036107e5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff9091169082906000906107aa576107aa61221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f460e08801886121ae565b858181106108045761080461221d565b9050602002016020810190610819919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036108be577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff909116908290859081106108835761088361221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008184815181106108d2576108d261221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c91906123a9565b87359550905060005b84811015610c8157600081600101905060008482815181106109995761099961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168584815181106109c9576109c961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610a5860405180608001604052808a81526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878681518110610a2c57610a2c61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018b815250611904565b8015610b61576000610a6e6101008c018c6121ae565b85818110610a7e57610a7e61221d565b9050602002016020810190610a93919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c91906123c2565b91505080610b5990612415565b985050610c6e565b6000610b716101008c018c6121ae565b85818110610b8157610b8161221d565b9050602002016020810190610b96919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5e91906123c2565b509050610c6a81612415565b9850505b610c76611a93565b503094509050610975565b50610c9b85610c9660808a0160608b0161244d565b611af3565b851015610cd4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828581518110610ce857610ce861221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8291906123a9565b905081811080610d9a5750610d978683612471565b81105b15610dd1576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e20610de460e08a0160c08b0161224c565b848781518110610df657610df661221d565b60200260200101518a6080016020810190610e11919061244d565b61ffff168b602001358a611b1a565b95506000610e3160e08a018a6121ae565b87818110610e4157610e4161221d565b9050602002016020810190610e56919061224c565b73ffffffffffffffffffffffffffffffffffffffff1603610fc5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b5060009250610f2891505060608a0160408b0161224c565b73ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610f7f576040519150601f19603f3d011682016040523d82523d6000602084013e610f84565b606091505b5050905080610fbf576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611018565b611018610fd860608a0160408b0161224c565b87858881518110610feb57610feb61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611bd39092919063ffffffff16565b61102560e08901896121ae565b868181106110355761103561221d565b905060200201602081019061104a919061224c565b73ffffffffffffffffffffffffffffffffffffffff1661106d60e08a018a6121ae565b600081811061107e5761107e61221d565b9050602002016020810190611093919061224c565b73ffffffffffffffffffffffffffffffffffffffff166110b960e08b0160c08c0161224c565b604080518c358152602081018b905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050505092915050565b6000808061112c60e0860160c0870161224c565b73ffffffffffffffffffffffffffffffffffffffff161490506000816111615761115c60e0860160c0870161224c565b61119a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b90506000806111b0610100880160e0890161224c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576111dc610100870160e0880161224c565b61121a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae91906123a9565b905060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610905061134860405180608001604052808a608001358152602001876113065733611308565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200189815250611904565b80156114335760006113626101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b013560448201526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e91906123c2565b9150508061142b90612415565b965050611522565b60006114476101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b0135604482015273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151291906123c2565b50905061151e81612415565b9650505b61152a611a93565b611543610100890135610c9660808b0160608c0161244d565b86101561157c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d91906123a9565b90508281108061162557506116228784612471565b81105b1561165c576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61169061166f60408b0160208c0161224c565b8561168060608d0160408e0161244d565b61ffff168c61010001358b611b1a565b965060006116a56101008b0160e08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1603611811577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d80600081146117cb576040519150601f19603f3d011682016040523d82523d6000602084013e6117d0565b606091505b505090508061180b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061183f565b61183f61182160208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff86169089611bd3565b6118506101008a0160e08b0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661187660e08b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661189c60408c0160208d0161224c565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c608001358b6040516118f0929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611962576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611af1576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612710611b028382612484565b611b109061ffff16856124a6565b6104f591906124bd565b60006107d0841115611b61576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611b73575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611ba95760646032840204611bac565b60005b9050808303838214611bc457611bc48a8a8484611c65565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611c60908490611d2d565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611d8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e3c9092919063ffffffff16565b9050805160001480611db0575080806020019051810190611db091906124f8565b611c60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611b58565b6060611e4b8484600085611e53565b949350505050565b606082471015611ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611b58565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611f0e919061253e565b60006040518083038185875af1925050503d8060008114611f4b576040519150601f19603f3d011682016040523d82523d6000602084013e611f50565b606091505b5091509150611f6187838387611f6c565b979650505050505050565b60608315612002578251600003611ffb5773ffffffffffffffffffffffffffffffffffffffff85163b611ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611b58565b5081611e4b565b611e4b83838151156120175781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b58919061255a565b6000610120828403121561205e57600080fd5b50919050565b60006020828403121561207657600080fd5b813567ffffffffffffffff81111561208d57600080fd5b611e4b8482850161204b565b6000610140828403121561205e57600080fd5b600061014082840312156120bf57600080fd5b6104f58383612099565b60006040828403121561205e57600080fd5b60008061016083850312156120ef57600080fd5b6120f98484612099565b915061014083013567ffffffffffffffff81111561211657600080fd5b612122858286016120c9565b9150509250929050565b6000806040838503121561213f57600080fd5b823567ffffffffffffffff8082111561215757600080fd5b6121638683870161204b565b9350602085013591508082111561217957600080fd5b50612122858286016120c9565b60006020828403121561219857600080fd5b813565ffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126121e357600080fd5b83018035915067ffffffffffffffff8211156121fe57600080fd5b6020019150600581901b360382131561221657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561225e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122b757600080fd5b83018035915067ffffffffffffffff8211156122d257600080fd5b60200191503681900382131561221657600080fd5b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156123bb57600080fd5b5051919050565b600080604083850312156123d557600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203612446576124466123e6565b5060000390565b60006020828403121561245f57600080fd5b813561ffff811681146104f557600080fd5b80820180821115610249576102496123e6565b61ffff82811682821603908082111561249f5761249f6123e6565b5092915050565b8082028115828204841417610249576102496123e6565b6000826124f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561250a57600080fd5b815180151581146104f557600080fd5b60005b8381101561253557818101518382015260200161251d565b50506000910152565b6000825161255081846020870161251a565b9190910192915050565b602081526000825180602084015261257981604085016020870161251a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122020ef15a82dfe9e15884ad78a08e0e295c6c50a821511c6e99799a1a517eefc3564736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003e5760003560e01c80626ee8b6146100435780635576abd114610068578063a33aea141461007b578063cda932d11461009b575b600080fd5b610056610051366004612064565b6100bb565b60405190815260200160405180910390f35b6100566100763660046120ac565b61024f565b34801561008757600080fd5b506100566100963660046120db565b6103b2565b3480156100a757600080fd5b506100566100b636600461212c565b6104fc565b60006100cd60c0830160a08401612186565b65ffffffffffff1642111561010e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061011d60e08401846121ae565b600081811061012e5761012e61221d565b9050602002016020810190610143919061224c565b73ffffffffffffffffffffffffffffffffffffffff160361023e5734823514610198576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b50505050505b61024982600061065b565b92915050565b600061026160c0830160a08401612186565b65ffffffffffff164211156102a2576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b460e0840160c0850161224c565b73ffffffffffffffffffffffffffffffffffffffff16036103a7577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660808301353414610344576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561038c57600080fd5b505af11580156103a0573d6000803e3d6000fd5b5050505050505b610249826000611118565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b57091339181906060820190819061041a908b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff908116825260808b013516602082015260400161045260c08b0160a08c01612186565b65ffffffffffff9081168252893516602091820152908252309082015260400161048260c0890160a08a01612186565b65ffffffffffff1690526104996020870187612282565b6040518563ffffffff1660e01b81526004016104b894939291906122e7565b600060405180830381600087803b1580156104d257600080fd5b505af11580156104e6573d6000803e3d6000fd5b505050506104f5836001611118565b9392505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610561908b018b6121ae565b60008181106105725761057261221d565b9050602002016020810190610587919061224c565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016105bc60c08b0160a08c01612186565b65ffffffffffff908116825289351660209182015290825230908201526040016105ec60c0890160a08a01612186565b65ffffffffffff1690526106036020870187612282565b6040518563ffffffff1660e01b815260040161062294939291906122e7565b600060405180830381600087803b15801561063c57600080fd5b505af1158015610650573d6000803e3d6000fd5b505050506104f58360015b60008061066c6101008501856121ae565b9150600090508061068060e08701876121ae565b60008181106106915761069161221d565b90506020020160208101906106a6919061224c565b73ffffffffffffffffffffffffffffffffffffffff16146106c757336106c9565b305b905060006106da60e08701876121ae565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061071b9250505060e08801886121ae565b600081811061072c5761072c61221d565b9050602002016020810190610741919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036107e5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff9091169082906000906107aa576107aa61221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f460e08801886121ae565b858181106108045761080461221d565b9050602002016020810190610819919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036108be577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff909116908290859081106108835761088361221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008184815181106108d2576108d261221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c91906123a9565b87359550905060005b84811015610c8157600081600101905060008482815181106109995761099961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168584815181106109c9576109c961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610a5860405180608001604052808a81526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878681518110610a2c57610a2c61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018b815250611904565b8015610b61576000610a6e6101008c018c6121ae565b85818110610a7e57610a7e61221d565b9050602002016020810190610a93919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c91906123c2565b91505080610b5990612415565b985050610c6e565b6000610b716101008c018c6121ae565b85818110610b8157610b8161221d565b9050602002016020810190610b96919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5e91906123c2565b509050610c6a81612415565b9850505b610c76611a93565b503094509050610975565b50610c9b85610c9660808a0160608b0161244d565b611af3565b851015610cd4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828581518110610ce857610ce861221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8291906123a9565b905081811080610d9a5750610d978683612471565b81105b15610dd1576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e20610de460e08a0160c08b0161224c565b848781518110610df657610df661221d565b60200260200101518a6080016020810190610e11919061244d565b61ffff168b602001358a611b1a565b95506000610e3160e08a018a6121ae565b87818110610e4157610e4161221d565b9050602002016020810190610e56919061224c565b73ffffffffffffffffffffffffffffffffffffffff1603610fc5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b5060009250610f2891505060608a0160408b0161224c565b73ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610f7f576040519150601f19603f3d011682016040523d82523d6000602084013e610f84565b606091505b5050905080610fbf576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611018565b611018610fd860608a0160408b0161224c565b87858881518110610feb57610feb61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611bd39092919063ffffffff16565b61102560e08901896121ae565b868181106110355761103561221d565b905060200201602081019061104a919061224c565b73ffffffffffffffffffffffffffffffffffffffff1661106d60e08a018a6121ae565b600081811061107e5761107e61221d565b9050602002016020810190611093919061224c565b73ffffffffffffffffffffffffffffffffffffffff166110b960e08b0160c08c0161224c565b604080518c358152602081018b905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050505092915050565b6000808061112c60e0860160c0870161224c565b73ffffffffffffffffffffffffffffffffffffffff161490506000816111615761115c60e0860160c0870161224c565b61119a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b90506000806111b0610100880160e0890161224c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576111dc610100870160e0880161224c565b61121a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae91906123a9565b905060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610905061134860405180608001604052808a608001358152602001876113065733611308565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200189815250611904565b80156114335760006113626101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b013560448201526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e91906123c2565b9150508061142b90612415565b965050611522565b60006114476101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b0135604482015273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151291906123c2565b50905061151e81612415565b9650505b61152a611a93565b611543610100890135610c9660808b0160608c0161244d565b86101561157c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d91906123a9565b90508281108061162557506116228784612471565b81105b1561165c576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61169061166f60408b0160208c0161224c565b8561168060608d0160408e0161244d565b61ffff168c61010001358b611b1a565b965060006116a56101008b0160e08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1603611811577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d80600081146117cb576040519150601f19603f3d011682016040523d82523d6000602084013e6117d0565b606091505b505090508061180b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061183f565b61183f61182160208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff86169089611bd3565b6118506101008a0160e08b0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661187660e08b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661189c60408c0160208d0161224c565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c608001358b6040516118f0929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611962576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611af1576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612710611b028382612484565b611b109061ffff16856124a6565b6104f591906124bd565b60006107d0841115611b61576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611b73575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611ba95760646032840204611bac565b60005b9050808303838214611bc457611bc48a8a8484611c65565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611c60908490611d2d565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611d8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e3c9092919063ffffffff16565b9050805160001480611db0575080806020019051810190611db091906124f8565b611c60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611b58565b6060611e4b8484600085611e53565b949350505050565b606082471015611ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611b58565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611f0e919061253e565b60006040518083038185875af1925050503d8060008114611f4b576040519150601f19603f3d011682016040523d82523d6000602084013e611f50565b606091505b5091509150611f6187838387611f6c565b979650505050505050565b60608315612002578251600003611ffb5773ffffffffffffffffffffffffffffffffffffffff85163b611ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611b58565b5081611e4b565b611e4b83838151156120175781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b58919061255a565b6000610120828403121561205e57600080fd5b50919050565b60006020828403121561207657600080fd5b813567ffffffffffffffff81111561208d57600080fd5b611e4b8482850161204b565b6000610140828403121561205e57600080fd5b600061014082840312156120bf57600080fd5b6104f58383612099565b60006040828403121561205e57600080fd5b60008061016083850312156120ef57600080fd5b6120f98484612099565b915061014083013567ffffffffffffffff81111561211657600080fd5b612122858286016120c9565b9150509250929050565b6000806040838503121561213f57600080fd5b823567ffffffffffffffff8082111561215757600080fd5b6121638683870161204b565b9350602085013591508082111561217957600080fd5b50612122858286016120c9565b60006020828403121561219857600080fd5b813565ffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126121e357600080fd5b83018035915067ffffffffffffffff8211156121fe57600080fd5b6020019150600581901b360382131561221657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561225e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122b757600080fd5b83018035915067ffffffffffffffff8211156122d257600080fd5b60200191503681900382131561221657600080fd5b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156123bb57600080fd5b5051919050565b600080604083850312156123d557600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203612446576124466123e6565b5060000390565b60006020828403121561245f57600080fd5b813561ffff811681146104f557600080fd5b80820180821115610249576102496123e6565b61ffff82811682821603908082111561249f5761249f6123e6565b5092915050565b8082028115828204841417610249576102496123e6565b6000826124f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561250a57600080fd5b815180151581146104f557600080fd5b60005b8381101561253557818101518382015260200161251d565b50506000910152565b6000825161255081846020870161251a565b9190910192915050565b602081526000825180602084015261257981604085016020870161251a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122020ef15a82dfe9e15884ad78a08e0e295c6c50a821511c6e99799a1a517eefc3564736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/bsc/WarpLink.json b/packages/hardhat/deployments/bsc/WarpLink.json index 861baaf9..b8114505 100644 --- a/packages/hardhat/deployments/bsc/WarpLink.json +++ b/packages/hardhat/deployments/bsc/WarpLink.json @@ -1,5 +1,5 @@ { - "address": "0xC28572E1a008760b204495AF30041da767F18d1B", + "address": "0xb80006779706b0f4FAd8D729B7a92b8Ca3bB6252", "abi": [ { "inputs": [], @@ -249,6 +249,71 @@ "stateMutability": "nonpayable", "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" + } + ], + "name": "warpLinkEngage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -326,34 +391,34 @@ "type": "tuple" } ], - "name": "warpLinkEngage", + "name": "warpLinkEngagePermit", "outputs": [], "stateMutability": "payable", "type": "function" } ], - "transactionHash": "0xa75ae3d7a2be58245b9a415f1043e10d732ade52a009e7a7448221f6b00d77d0", + "transactionHash": "0xb8126725e006c7f8d2040ba24cd78fb919c6e72a7dc96829e90a5bb00e27a163", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xC28572E1a008760b204495AF30041da767F18d1B", - "transactionIndex": 67, - "gasUsed": "4672465", + "contractAddress": "0xb80006779706b0f4FAd8D729B7a92b8Ca3bB6252", + "transactionIndex": 41, + "gasUsed": "5125542", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc2f4d0554d0b1309f0baca2486f3a57f1a22e4334fa15b0b535c9690afd6b603", - "transactionHash": "0xa75ae3d7a2be58245b9a415f1043e10d732ade52a009e7a7448221f6b00d77d0", + "blockHash": "0xa5f32abc794fc079ba1fae64db9b29b29f8cf24a09b30c411b5738f855349f20", + "transactionHash": "0xb8126725e006c7f8d2040ba24cd78fb919c6e72a7dc96829e90a5bb00e27a163", "logs": [], - "blockNumber": 32959701, - "cumulativeGasUsed": "12667916", + "blockNumber": 33248495, + "cumulativeGasUsed": "8657893", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 6, - "solcInputHash": "62b3897f582f2743ff2d0ddfebde07d0", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"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\":\"InvalidSgReceiveSrcAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSgReceiverSender\",\"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\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"bytes\",\"name\":\"_srcAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountLD\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sgReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{\"sgReceive(uint16,bytes,uint256,address,uint256,bytes)\":{\"notice\":\"Cross-chain callback from Stargate The tokens have already been received by this contract, `t.payer` is set to this contract before `sgReceive` is called by the router. The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the same message more than once. The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the Stargate composer be compromised, an attacker can drain this contract. If the payload can not be decoded, tokens are left in this contract. If execution runs out of gas, tokens are left in this contract. If an error occurs during engage, such as insufficient output amount, tokens are refunded to the recipient. See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\"}},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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';\\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\\n bytes payload;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n address paramTokenIn;\\n uint256 paramAmountIn;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint48 paramDeadline;\\n uint256 amount;\\n address payer;\\n address token;\\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 useEth: isFromEth || isToEth,\\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 * Cross-chain callback from Stargate\\n *\\n * The tokens have already been received by this contract, `t.payer` is set to this contract\\n * before `sgReceive` is called by the router.\\n *\\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\\n * same message more than once.\\n *\\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\\n * Stargate composer be compromised, an attacker can drain this contract.\\n *\\n * If the payload can not be decoded, tokens are left in this contract.\\n * If execution runs out of gas, tokens are left in this contract.\\n *\\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\\n * to the recipient.\\n *\\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\\n */\\n function sgReceive(\\n uint16, // _srcChainId\\n bytes memory _srcAddress,\\n uint256, // _nonce\\n address _token,\\n uint256 amountLD,\\n bytes memory payload\\n ) external {\\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\\n revert InvalidSgReceiverSender();\\n }\\n\\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\\n // From https://ethereum.stackexchange.com/a/50528\\n address srcAddress;\\n\\n assembly {\\n srcAddress := mload(add(_srcAddress, 20))\\n }\\n\\n if (srcAddress != address(this)) {\\n // NOTE: This assumes that this contract is deployed at the same address on every chain\\n revert InvalidSgReceiveSrcAddress();\\n }\\n\\n Params memory params = abi.decode(payload, (Params));\\n\\n if (params.tokenIn == address(0)) {\\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\\n // otherwise because `_token` may be different on this chain\\n _token = address(0);\\n }\\n\\n try\\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\\n Params({\\n partner: params.partner,\\n feeBps: params.feeBps,\\n slippageBps: params.slippageBps,\\n recipient: params.recipient,\\n tokenIn: _token,\\n tokenOut: params.tokenOut,\\n amountIn: amountLD,\\n amountOut: params.amountOut,\\n deadline: params.deadline,\\n commands: params.commands\\n }),\\n PermitParams({nonce: 0, signature: ''})\\n )\\n {} catch {\\n // Refund tokens to the recipient\\n if (_token == address(0)) {\\n payable(params.recipient).transfer(amountLD);\\n } else {\\n IERC20(_token).safeTransfer(params.recipient, amountLD);\\n }\\n }\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\\n * in this function.\\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 * - dstGasForCall (uint32)\\n * - tokenOut (address) when `dstGasForCall` > 0\\n * - amountOut (uint256) when `dstGasForCall` > 0\\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n params.dstGasForCall = stream.readUint32();\\n\\n if (params.dstGasForCall > 0) {\\n // NOTE: `amountIn` is left as zero\\n Params memory destParams;\\n destParams.partner = t.paramPartner;\\n destParams.feeBps = t.paramFeeBps;\\n destParams.slippageBps = t.paramSlippageBps;\\n destParams.recipient = t.paramRecipient;\\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\\n // the same address as on this chain\\n destParams.tokenIn = t.token;\\n destParams.tokenOut = stream.readAddress();\\n destParams.amountOut = stream.readUint256();\\n destParams.deadline = t.paramDeadline;\\n destParams.commands = stream.readBytes();\\n params.payload = abi.encode(destParams);\\n }\\n\\n if (t.token != t.paramTokenIn) {\\n if (params.payload.length == 0) {\\n // If the tokens are being delivered directly to the recipient without a second\\n // WarpLink engage, the fee is charged on this chain\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibStarVault.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n }\\n\\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\\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. When there is a payload, the composer is used, else the router\\n IERC20(t.token).forceApprove(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\\n t.amount\\n );\\n }\\n\\n t.jumped = 1;\\n\\n // Swap on the composer if there is a payload, else the router\\n IStargateRouter(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\\n ).swap{\\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\\n }({\\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\\n // more on the other chain. It also assumes the tokens are of nearly equal value\\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: params.dstGasForCall,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n // NOTE: This assumes the contract is deployed at the same address on every chain.\\n // If this is not the case, a new param needs to be added with the next WarpLink address\\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\\n _payload: params.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.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\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 // The signature is omitted when `warpLinkEngage` is called from `sgReceive`\\n if (permit.signature.length > 0) {\\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\\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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0x198e2bb767f975464f62ecb8578721d7516f8da1302b3acfd3c622258de1320e\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\\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 error InvalidSgReceiverSender();\\n error InvalidSgReceiveSrcAddress();\\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\":\"0xc1d8b9ba2a1f8300c00adc2c66fd51da23bb40db78ce5b7fe270bb7ee77e923e\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IStargateReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\n\\ninterface IStargateReceiver {\\n function sgReceive(\\n uint16 _srcChainId, // the remote chainId sending the tokens\\n bytes memory _srcAddress, // the remote Bridge address\\n uint256 _nonce,\\n address _token, // the token contract on the local chain\\n uint256 amountLD, // the qty of local _token contract tokens\\n bytes memory payload\\n ) external;\\n}\\n\",\"keccak256\":\"0x7fd06c09139156a4f09a77eac28e453a1d2041a8cf01a108fc875c65192cb637\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50615400806100206000396000f3fe6080604052600436106100295760003560e01c8063ab8236f31461002e578063dc7b39db14610050575b600080fd5b34801561003a57600080fd5b5061004e610049366004614a1e565b610063565b005b61004e61005e366004614af2565b61036f565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff1633146100d6576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461012a576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906101409190614c9f565b608081015190915073ffffffffffffffffffffffffffffffffffffffff1661016757600094505b3063dc7b39db73ffffffffffffffffffffffffffffffffffffffff871615610190576000610192565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff168152602001856101200151815250604051806040016040528060008152602001604051806020016040528060008152508152506040518463ffffffff1660e01b81526004016102a4929190614efc565b6000604051808303818588803b1580156102bd57600080fd5b505af1935050505080156102cf575060015b6103655773ffffffffffffffffffffffffffffffffffffffff851661033e57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610338573d6000803e3d6000fd5b50610365565b60608101516103659073ffffffffffffffffffffffffffffffffffffffff87169086610981565b5050505050505050565b81610100015165ffffffffffff164211156103b6576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015161ffff9081169184019190915260408086018051831660c08087019182526060808a01518716948801949094526080808a01805188169589019590955290890180519188019190915260e0808a015160a0890152925190941690526101008088015165ffffffffffff169186019190915291519184019190915280518216610140840152511661052a578260c00151341015610509576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08301516105189034614f63565b610180820152306101208201526106bd565b336101208201523461018082015260006105476020840184614f76565b905011156106bd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff1681525085806020019061066b9190614f76565b6040518563ffffffff1660e01b815260040161068a9493929190614fe2565b600060405180830381600087803b1580156106a457600080fd5b505af11580156106b8573d6000803e3d6000fd5b505050505b60006106e2846101200151604080518082019091528181528151909101602082015290565b90506106ee8183610a5a565b61010081015161014082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610755576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107678660e001518760400151610c37565b8210156107a0576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361016001516001036107b557505050505050565b6107d686600001518760a00151886020015161ffff168960e0015186610c65565b915081600003610812576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661087d57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610877573d6000803e3d6000fd5b506108a4565b60608601516108a49073ffffffffffffffffffffffffffffffffffffffff83169084610981565b610180840151156108e257610180840151604051339180156108fc02916000818181858888f193505050501580156108e0573d6000803e3d6000fd5b505b8560a0015173ffffffffffffffffffffffffffffffffffffffff16866080015173ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c0015186604051610971929190918252602082015260400190565b60405180910390a4505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610d1e565b505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526000610ad58480516001018051915290565b60ff16905060005b81811015610c2b576000610af78680516001018051915290565b60ff16905060018103610b1457610b0d85610e2d565b9450610c18565b60028103610b2557610b0d85610ff5565b60038103610b3757610b0d8686611254565b60048103610b4957610b0d8686611832565b60058103610b5b57610b0d8686611bb9565b60068103610b6d57610b0d8686612367565b60078103610b7f57610b0d8686612891565b60088103610b9157610b0d8686612dcf565b60098103610be657610ba4600184614f63565b8214610bdc576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d8686613205565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5080610c23816150a4565b915050610add565b50829150505b92915050565b6000612710610c4683826150dc565b610c549061ffff16856150f7565b610c5e919061513d565b9392505050565b60006107d0841115610cac576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610cbe575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610cf45760646032840204610cf7565b60005b9050808303838214610d0f57610d0f8a8a84846139d7565b50505090910395945050505050565b6000610d80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613a9f9092919063ffffffff16565b9050805160001480610da1575080806020019051810190610da19190615178565b610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ca3565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408082018390526101608201839052610180820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610f0a576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014610f5e576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50959695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146110db576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff8116301480159061110957306101208601525b600061014086015280156111bc57600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505050505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916112199160040190815260200190565b600060405180830381600087803b15801561123357600080fd5b505af1158015611247573d6000803e3d6000fd5b5096979650505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff1661130f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff90911603611404576113ff816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b6114e0565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156114c057600080fd5b505af11580156114d4573d6000803e3d6000fd5b50503061012086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161158657905b606083015161010086015161ffff61271092830316918402908202908101908302816115b4576115b461510e565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e9190615208565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161168457876101000151611687565b60005b866040015161169757600061169e565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561170857600080fd5b505af115801561171c573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b49190615208565b9050818110806117d257506101008701516117cf9083615221565b81105b15611809576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915260006118ad8480516001018051915290565b60ff16905060008361010001519050600060028310156118f9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611b84576000611914600188614f63565b82106119205785611951565b6127106119338b80516002018051915290565b61ffff168a610100015161194791906150f7565b611951919061513d565b90508581111561198d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119978187614f63565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261012080820183815261014080840185815261016085018690526101808501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d015116909152909650611a368b82610a5a565b9050806101600151600103611a77576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611a945780610120015193508061014001519450611b68565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614611afe576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614611b68576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100810151611b789087615221565b955050506001016118ff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152611c4660405180606001604052806060815260200160608152602001606081525090565b6000611c588580516001018051915290565b60ff169050611c68816001615221565b67ffffffffffffffff811115611c8057611c806148ad565b604051908082528060200260200182016040528015611ca9578160200160208202803683370190505b508083526101408501518151909190600090611cc757611cc7615234565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b81811015611d6057855160140180519087528351611d23836001615221565b81518110611d3357611d33615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611d04565b50611d6b8582613ab6565b6020830152611d7a8582613b58565b6040830152815180516000919083908110611d9757611d97615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e319190615208565b90506000611e52846040015187610100015186600001518760200151613be1565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff1603611ee457611edf8460200151600081518110611ea657611ea6615234565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b611fe3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c78516929190600090611f4357611f43615234565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b8152600401611fa9949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015611fc357600080fd5b505af1158015611fd7573d6000803e3d6000fd5b50503061012089015250505b60005b838110156121e7576000611ffb826001615221565b905060008660000151828151811061201557612015615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168760000151848151811061204957612049615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612073576000612076565b60015b90506000600288600001515161208c9190614f63565b841061209857306120b7565b876020015183815181106120ae576120ae615234565b60200260200101515b9050876020015184815181106120cf576120cf615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836121165786858151811061210957612109615234565b6020026020010151612119565b60005b84612125576000612140565b87868151811061213757612137615234565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156121c057600080fd5b505af11580156121d4573d6000803e3d6000fd5b505060019095019450611fe69350505050565b5060008460000151848151811061220057612200615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229a9190615208565b905081600183516122ab9190614f63565b815181106122bb576122bb615234565b602002602001015187610100018181525050828110806122e957506101008701516122e69084615221565b81105b15612320576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845180518590811061233457612334615234565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff90811660208301526101408401511661247a576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156124e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250c9190615208565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff161090506125a86040518060600160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff16815250613e16565b801561268c5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561264f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126739190615263565b9150508061268090615287565b61010087015250612774565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561273c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127609190615263565b50905061276c81615287565b610100870152505b61277c613f7f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e9190615208565b90508281108061282c57506101008601516128299084615221565b81105b15612863576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261291e60405180606001604052806060815260200160608152602001606081525090565b60006129308580516001018051915290565b60ff16905061293f8582613ab6565b825261294b8582613ab6565b60208301528151600090612960600184614f63565b8151811061297057612970615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156129eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0f9190615208565b905060005b83811015612cd75760008115612a4e578551612a31600184614f63565b81518110612a4157612a41615234565b6020026020010151612a55565b8761014001515b905085600001518281518110612a6d57612a6d615234565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516060810182526101008d015181526101208d01518416948101949094529184169183018290521190612ace90613e16565b82600003612ade57306101208a01525b600087602001518481518110612af657612af6615234565b602002602001015190508115612be0576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc79190615263565b91505080612bd490615287565b6101008c015250612cc4565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb09190615263565b509050612cbc81615287565b6101008c0152505b612ccc613f7f565b505050600101612a14565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6e9190615208565b905081811080612d8c5750610100870151612d899083615221565b81105b15612dc3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff9283161592918216159130911614613006577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612fe657600080fd5b505af1158015612ffa573d6000803e3d6000fd5b50503061012088015250505b6000816130a35783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561307a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309e9190615208565b6130a5565b475b9050826130e5576130e5846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff16613fdf9092919063ffffffff16565b61312a84608001518560a0015186602001518661310357600061310a565b8961010001515b886040015189606001518c610100015160008b8061312557508a5b6140d5565b6000826131c75784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561319e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c29190615208565b6131c9565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506131f38282614f63565b61010088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526132a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613431576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff166101008201528451602080820180519092010186526101208201526040516133fc9082906020016152bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613543578060800151516000036134a5578251610140840151602085015161010086015161349e93929161ffff169080610c65565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3866080015187610100015160405161353a929190918252602082015260400190565b60405180910390a45b6135558360a001518460c00151610c37565b8361010001511015613593576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff91821691161561377f5761012084015173ffffffffffffffffffffffffffffffffffffffff1630146136d1577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156136b157600080fd5b505af11580156136c5573d6000803e3d6000fd5b50503061012087015250505b61377f8260800151516000146136e75781613756565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613732573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061375691906152d2565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff169190613fdf565b6001610160850152608082015151156137985780613807565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380791906152d2565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff16146138665785610180015161387c565b85610180015186610100015161387c9190615221565b8451602086015160408701516101008a015160c08b01513091906138a1908290610c37565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c6080015151116138e7578d604001516138e9565b305b604051602001613924919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b16835261399499989796959493926004016152ef565b6000604051808303818588803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b5050600061018088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060613aae84846000856145d1565b949350505050565b60608167ffffffffffffffff811115613ad157613ad16148ad565b604051908082528060200260200182016040528015613afa578160200160208202803683370190505b50905060005b82811015613b515783516014018051908552828281518110613b2457613b24615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613b00565b5092915050565b60608167ffffffffffffffff811115613b7357613b736148ad565b604051908082528060200260200182016040528015613b9c578160200160208202803683370190505b50905060005b82811015613b515783516002018051908552828281518110613bc657613bc6615234565b61ffff90921660209283029190910190910152600101613ba2565b805182516060919067ffffffffffffffff811115613c0157613c016148ad565b604051908082528060200260200182016040528015613c2a578160200160208202803683370190505b5091508482600081518110613c4157613c41615234565b60200260200101818152505060005b81811015613e0c576000858281518110613c6c57613c6c615234565b60200260200101519050600086836001613c869190615221565b81518110613c9657613c96615234565b602002602001015190506000898481518110613cb457613cb4615234565b6020026020010151612710613cc991906150dc565b61ffff169050600080888681518110613ce457613ce4615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d5a91906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115613db557905b828b0282612710020181848d020281613dd057613dd061510e565b049a508a88613de0886001615221565b81518110613df057613df0615234565b6020908102919091010152505060019093019250613c50915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613e74576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613fdd576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261406b84826146ea565b6140cf5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526140c59085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109d3565b6140cf8482610d1e565b50505050565b8860ff1660010361420357871561418e576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561417057600080fd5b505af1158015614184573d6000803e3d6000fd5b50505050506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614157565b8860ff166002036143435787156142ce576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156142a3573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906142c89190615208565b506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614285565b8860ff166003036144e45787156143c1576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614285565b801561443b576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614285565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af11580156144c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c89190615208565b8860ff16600403614594578715614527576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614157565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b606082471015614663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ca3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161468c919061539b565b60006040518083038185875af1925050503d80600081146146c9576040519150601f19603f3d011682016040523d82523d6000602084013e6146ce565b606091505b50915091506146df878383876147ab565b979650505050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614714919061539b565b6000604051808303816000865af19150503d8060008114614751576040519150601f19603f3d011682016040523d82523d6000602084013e614756565b606091505b50915091508180156147805750805115806147805750808060200190518101906147809190615178565b80156147a2575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060831561484157825160000361483a5773ffffffffffffffffffffffffffffffffffffffff85163b61483a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca3565b5081613aae565b613aae83838151156148565781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca391906153b7565b61ffff8116811461489a57600080fd5b50565b80356148a88161488a565b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614900576149006148ad565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561494d5761494d6148ad565b604052919050565b600067ffffffffffffffff82111561496f5761496f6148ad565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149ac57600080fd5b81356149bf6149ba82614955565b614906565b8181528460208386010111156149d457600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461489a57600080fd5b80356148a8816149f1565b60008060008060008060c08789031215614a3757600080fd5b8635614a428161488a565b9550602087013567ffffffffffffffff80821115614a5f57600080fd5b614a6b8a838b0161499b565b96506040890135955060608901359150614a84826149f1565b9093506080880135925060a08801359080821115614aa157600080fd5b50614aae89828a0161499b565b9150509295509295509295565b65ffffffffffff8116811461489a57600080fd5b80356148a881614abb565b600060408284031215614aec57600080fd5b50919050565b60008060408385031215614b0557600080fd5b823567ffffffffffffffff80821115614b1d57600080fd5b908401906101408287031215614b3257600080fd5b614b3a6148dc565b614b4383614a13565b8152614b516020840161489d565b6020820152614b626040840161489d565b6040820152614b7360608401614a13565b6060820152614b8460808401614a13565b6080820152614b9560a08401614a13565b60a082015260c083013560c082015260e083013560e0820152610100614bbc818501614acf565b908201526101208381013583811115614bd457600080fd5b614be08982870161499b565b828401525050809450506020850135915080821115614bfe57600080fd5b50614c0b85828601614ada565b9150509250929050565b80516148a8816149f1565b80516148a88161488a565b80516148a881614abb565b60005b83811015614c51578181015183820152602001614c39565b50506000910152565b600082601f830112614c6b57600080fd5b8151614c796149ba82614955565b818152846020838601011115614c8e57600080fd5b613aae826020830160208701614c36565b600060208284031215614cb157600080fd5b815167ffffffffffffffff80821115614cc957600080fd5b908301906101408286031215614cde57600080fd5b614ce66148dc565b614cef83614c15565b8152614cfd60208401614c20565b6020820152614d0e60408401614c20565b6040820152614d1f60608401614c15565b6060820152614d3060808401614c15565b6080820152614d4160a08401614c15565b60a082015260c083015160c082015260e083015160e0820152610100614d68818501614c2b565b908201526101208381015183811115614d8057600080fd5b614d8c88828701614c5a565b918301919091525095945050505050565b60008151808452614db5816020860160208601614c36565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006101406020830151614e1b602086018261ffff169052565b506040830151614e31604086018261ffff169052565b506060830151614e59606086018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151614e81608086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614ea960a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015160c085015260e083015160e085015261010080840151614ed88287018265ffffffffffff169052565b5050610120808401518282870152614ef283870182614d9d565b9695505050505050565b604081526000614f0f6040830185614de7565b828103602084015283518152602084015160406020830152614ef26040830182614d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c3157610c31614f34565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614fab57600080fd5b83018035915067ffffffffffffffff821115614fc657600080fd5b602001915036819003821315614fdb57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150d5576150d5614f34565b5060010190565b61ffff828116828216039080821115613b5157613b51614f34565b8082028115828204841417610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615173577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561518a57600080fd5b81518015158114610c5e57600080fd5b80516dffffffffffffffffffffffffffff811681146148a857600080fd5b6000806000606084860312156151cd57600080fd5b6151d68461519a565b92506151e46020850161519a565b9150604084015163ffffffff811681146151fd57600080fd5b809150509250925092565b60006020828403121561521a57600080fd5b5051919050565b80820180821115610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561527657600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036152b8576152b8614f34565b5060000390565b602081526000610c5e6020830184614de7565b6000602082840312156152e457600080fd5b8151610c5e816149f1565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615362610180840182614d9d565b905082810360e08401526153768186614d9d565b905082810361010084015261538b8185614d9d565b9c9b505050505050505050505050565b600082516153ad818460208701614c36565b9190910192915050565b602081526000610c5e6020830184614d9d56fea26469706673582212204eecdc76d361ea4a608ec1291a66f39b61f591d844e03c8f4164adb5e8c419c464736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c8063ab8236f31461002e578063dc7b39db14610050575b600080fd5b34801561003a57600080fd5b5061004e610049366004614a1e565b610063565b005b61004e61005e366004614af2565b61036f565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff1633146100d6576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461012a576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906101409190614c9f565b608081015190915073ffffffffffffffffffffffffffffffffffffffff1661016757600094505b3063dc7b39db73ffffffffffffffffffffffffffffffffffffffff871615610190576000610192565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff168152602001856101200151815250604051806040016040528060008152602001604051806020016040528060008152508152506040518463ffffffff1660e01b81526004016102a4929190614efc565b6000604051808303818588803b1580156102bd57600080fd5b505af1935050505080156102cf575060015b6103655773ffffffffffffffffffffffffffffffffffffffff851661033e57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610338573d6000803e3d6000fd5b50610365565b60608101516103659073ffffffffffffffffffffffffffffffffffffffff87169086610981565b5050505050505050565b81610100015165ffffffffffff164211156103b6576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015161ffff9081169184019190915260408086018051831660c08087019182526060808a01518716948801949094526080808a01805188169589019590955290890180519188019190915260e0808a015160a0890152925190941690526101008088015165ffffffffffff169186019190915291519184019190915280518216610140840152511661052a578260c00151341015610509576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08301516105189034614f63565b610180820152306101208201526106bd565b336101208201523461018082015260006105476020840184614f76565b905011156106bd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff1681525085806020019061066b9190614f76565b6040518563ffffffff1660e01b815260040161068a9493929190614fe2565b600060405180830381600087803b1580156106a457600080fd5b505af11580156106b8573d6000803e3d6000fd5b505050505b60006106e2846101200151604080518082019091528181528151909101602082015290565b90506106ee8183610a5a565b61010081015161014082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610755576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107678660e001518760400151610c37565b8210156107a0576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361016001516001036107b557505050505050565b6107d686600001518760a00151886020015161ffff168960e0015186610c65565b915081600003610812576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661087d57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610877573d6000803e3d6000fd5b506108a4565b60608601516108a49073ffffffffffffffffffffffffffffffffffffffff83169084610981565b610180840151156108e257610180840151604051339180156108fc02916000818181858888f193505050501580156108e0573d6000803e3d6000fd5b505b8560a0015173ffffffffffffffffffffffffffffffffffffffff16866080015173ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c0015186604051610971929190918252602082015260400190565b60405180910390a4505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610d1e565b505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526000610ad58480516001018051915290565b60ff16905060005b81811015610c2b576000610af78680516001018051915290565b60ff16905060018103610b1457610b0d85610e2d565b9450610c18565b60028103610b2557610b0d85610ff5565b60038103610b3757610b0d8686611254565b60048103610b4957610b0d8686611832565b60058103610b5b57610b0d8686611bb9565b60068103610b6d57610b0d8686612367565b60078103610b7f57610b0d8686612891565b60088103610b9157610b0d8686612dcf565b60098103610be657610ba4600184614f63565b8214610bdc576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d8686613205565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5080610c23816150a4565b915050610add565b50829150505b92915050565b6000612710610c4683826150dc565b610c549061ffff16856150f7565b610c5e919061513d565b9392505050565b60006107d0841115610cac576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610cbe575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610cf45760646032840204610cf7565b60005b9050808303838214610d0f57610d0f8a8a84846139d7565b50505090910395945050505050565b6000610d80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613a9f9092919063ffffffff16565b9050805160001480610da1575080806020019051810190610da19190615178565b610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ca3565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408082018390526101608201839052610180820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610f0a576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014610f5e576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50959695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146110db576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff8116301480159061110957306101208601525b600061014086015280156111bc57600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505050505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916112199160040190815260200190565b600060405180830381600087803b15801561123357600080fd5b505af1158015611247573d6000803e3d6000fd5b5096979650505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff1661130f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff90911603611404576113ff816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b6114e0565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156114c057600080fd5b505af11580156114d4573d6000803e3d6000fd5b50503061012086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161158657905b606083015161010086015161ffff61271092830316918402908202908101908302816115b4576115b461510e565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e9190615208565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161168457876101000151611687565b60005b866040015161169757600061169e565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561170857600080fd5b505af115801561171c573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b49190615208565b9050818110806117d257506101008701516117cf9083615221565b81105b15611809576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915260006118ad8480516001018051915290565b60ff16905060008361010001519050600060028310156118f9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611b84576000611914600188614f63565b82106119205785611951565b6127106119338b80516002018051915290565b61ffff168a610100015161194791906150f7565b611951919061513d565b90508581111561198d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119978187614f63565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261012080820183815261014080840185815261016085018690526101808501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d015116909152909650611a368b82610a5a565b9050806101600151600103611a77576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611a945780610120015193508061014001519450611b68565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614611afe576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614611b68576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100810151611b789087615221565b955050506001016118ff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152611c4660405180606001604052806060815260200160608152602001606081525090565b6000611c588580516001018051915290565b60ff169050611c68816001615221565b67ffffffffffffffff811115611c8057611c806148ad565b604051908082528060200260200182016040528015611ca9578160200160208202803683370190505b508083526101408501518151909190600090611cc757611cc7615234565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b81811015611d6057855160140180519087528351611d23836001615221565b81518110611d3357611d33615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611d04565b50611d6b8582613ab6565b6020830152611d7a8582613b58565b6040830152815180516000919083908110611d9757611d97615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e319190615208565b90506000611e52846040015187610100015186600001518760200151613be1565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff1603611ee457611edf8460200151600081518110611ea657611ea6615234565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b611fe3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c78516929190600090611f4357611f43615234565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b8152600401611fa9949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015611fc357600080fd5b505af1158015611fd7573d6000803e3d6000fd5b50503061012089015250505b60005b838110156121e7576000611ffb826001615221565b905060008660000151828151811061201557612015615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168760000151848151811061204957612049615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612073576000612076565b60015b90506000600288600001515161208c9190614f63565b841061209857306120b7565b876020015183815181106120ae576120ae615234565b60200260200101515b9050876020015184815181106120cf576120cf615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836121165786858151811061210957612109615234565b6020026020010151612119565b60005b84612125576000612140565b87868151811061213757612137615234565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156121c057600080fd5b505af11580156121d4573d6000803e3d6000fd5b505060019095019450611fe69350505050565b5060008460000151848151811061220057612200615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229a9190615208565b905081600183516122ab9190614f63565b815181106122bb576122bb615234565b602002602001015187610100018181525050828110806122e957506101008701516122e69084615221565b81105b15612320576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845180518590811061233457612334615234565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff90811660208301526101408401511661247a576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156124e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250c9190615208565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff161090506125a86040518060600160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff16815250613e16565b801561268c5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561264f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126739190615263565b9150508061268090615287565b61010087015250612774565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561273c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127609190615263565b50905061276c81615287565b610100870152505b61277c613f7f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e9190615208565b90508281108061282c57506101008601516128299084615221565b81105b15612863576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261291e60405180606001604052806060815260200160608152602001606081525090565b60006129308580516001018051915290565b60ff16905061293f8582613ab6565b825261294b8582613ab6565b60208301528151600090612960600184614f63565b8151811061297057612970615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156129eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0f9190615208565b905060005b83811015612cd75760008115612a4e578551612a31600184614f63565b81518110612a4157612a41615234565b6020026020010151612a55565b8761014001515b905085600001518281518110612a6d57612a6d615234565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516060810182526101008d015181526101208d01518416948101949094529184169183018290521190612ace90613e16565b82600003612ade57306101208a01525b600087602001518481518110612af657612af6615234565b602002602001015190508115612be0576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc79190615263565b91505080612bd490615287565b6101008c015250612cc4565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb09190615263565b509050612cbc81615287565b6101008c0152505b612ccc613f7f565b505050600101612a14565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6e9190615208565b905081811080612d8c5750610100870151612d899083615221565b81105b15612dc3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff9283161592918216159130911614613006577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612fe657600080fd5b505af1158015612ffa573d6000803e3d6000fd5b50503061012088015250505b6000816130a35783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561307a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309e9190615208565b6130a5565b475b9050826130e5576130e5846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff16613fdf9092919063ffffffff16565b61312a84608001518560a0015186602001518661310357600061310a565b8961010001515b886040015189606001518c610100015160008b8061312557508a5b6140d5565b6000826131c75784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561319e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c29190615208565b6131c9565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506131f38282614f63565b61010088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526132a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613431576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff166101008201528451602080820180519092010186526101208201526040516133fc9082906020016152bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613543578060800151516000036134a5578251610140840151602085015161010086015161349e93929161ffff169080610c65565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3866080015187610100015160405161353a929190918252602082015260400190565b60405180910390a45b6135558360a001518460c00151610c37565b8361010001511015613593576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff91821691161561377f5761012084015173ffffffffffffffffffffffffffffffffffffffff1630146136d1577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156136b157600080fd5b505af11580156136c5573d6000803e3d6000fd5b50503061012087015250505b61377f8260800151516000146136e75781613756565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613732573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061375691906152d2565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff169190613fdf565b6001610160850152608082015151156137985780613807565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380791906152d2565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff16146138665785610180015161387c565b85610180015186610100015161387c9190615221565b8451602086015160408701516101008a015160c08b01513091906138a1908290610c37565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c6080015151116138e7578d604001516138e9565b305b604051602001613924919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b16835261399499989796959493926004016152ef565b6000604051808303818588803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b5050600061018088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060613aae84846000856145d1565b949350505050565b60608167ffffffffffffffff811115613ad157613ad16148ad565b604051908082528060200260200182016040528015613afa578160200160208202803683370190505b50905060005b82811015613b515783516014018051908552828281518110613b2457613b24615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613b00565b5092915050565b60608167ffffffffffffffff811115613b7357613b736148ad565b604051908082528060200260200182016040528015613b9c578160200160208202803683370190505b50905060005b82811015613b515783516002018051908552828281518110613bc657613bc6615234565b61ffff90921660209283029190910190910152600101613ba2565b805182516060919067ffffffffffffffff811115613c0157613c016148ad565b604051908082528060200260200182016040528015613c2a578160200160208202803683370190505b5091508482600081518110613c4157613c41615234565b60200260200101818152505060005b81811015613e0c576000858281518110613c6c57613c6c615234565b60200260200101519050600086836001613c869190615221565b81518110613c9657613c96615234565b602002602001015190506000898481518110613cb457613cb4615234565b6020026020010151612710613cc991906150dc565b61ffff169050600080888681518110613ce457613ce4615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d5a91906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115613db557905b828b0282612710020181848d020281613dd057613dd061510e565b049a508a88613de0886001615221565b81518110613df057613df0615234565b6020908102919091010152505060019093019250613c50915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613e74576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613fdd576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261406b84826146ea565b6140cf5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526140c59085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109d3565b6140cf8482610d1e565b50505050565b8860ff1660010361420357871561418e576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561417057600080fd5b505af1158015614184573d6000803e3d6000fd5b50505050506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614157565b8860ff166002036143435787156142ce576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156142a3573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906142c89190615208565b506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614285565b8860ff166003036144e45787156143c1576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614285565b801561443b576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614285565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af11580156144c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c89190615208565b8860ff16600403614594578715614527576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614157565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b606082471015614663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ca3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161468c919061539b565b60006040518083038185875af1925050503d80600081146146c9576040519150601f19603f3d011682016040523d82523d6000602084013e6146ce565b606091505b50915091506146df878383876147ab565b979650505050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614714919061539b565b6000604051808303816000865af19150503d8060008114614751576040519150601f19603f3d011682016040523d82523d6000602084013e614756565b606091505b50915091508180156147805750805115806147805750808060200190518101906147809190615178565b80156147a2575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060831561484157825160000361483a5773ffffffffffffffffffffffffffffffffffffffff85163b61483a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca3565b5081613aae565b613aae83838151156148565781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca391906153b7565b61ffff8116811461489a57600080fd5b50565b80356148a88161488a565b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614900576149006148ad565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561494d5761494d6148ad565b604052919050565b600067ffffffffffffffff82111561496f5761496f6148ad565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149ac57600080fd5b81356149bf6149ba82614955565b614906565b8181528460208386010111156149d457600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461489a57600080fd5b80356148a8816149f1565b60008060008060008060c08789031215614a3757600080fd5b8635614a428161488a565b9550602087013567ffffffffffffffff80821115614a5f57600080fd5b614a6b8a838b0161499b565b96506040890135955060608901359150614a84826149f1565b9093506080880135925060a08801359080821115614aa157600080fd5b50614aae89828a0161499b565b9150509295509295509295565b65ffffffffffff8116811461489a57600080fd5b80356148a881614abb565b600060408284031215614aec57600080fd5b50919050565b60008060408385031215614b0557600080fd5b823567ffffffffffffffff80821115614b1d57600080fd5b908401906101408287031215614b3257600080fd5b614b3a6148dc565b614b4383614a13565b8152614b516020840161489d565b6020820152614b626040840161489d565b6040820152614b7360608401614a13565b6060820152614b8460808401614a13565b6080820152614b9560a08401614a13565b60a082015260c083013560c082015260e083013560e0820152610100614bbc818501614acf565b908201526101208381013583811115614bd457600080fd5b614be08982870161499b565b828401525050809450506020850135915080821115614bfe57600080fd5b50614c0b85828601614ada565b9150509250929050565b80516148a8816149f1565b80516148a88161488a565b80516148a881614abb565b60005b83811015614c51578181015183820152602001614c39565b50506000910152565b600082601f830112614c6b57600080fd5b8151614c796149ba82614955565b818152846020838601011115614c8e57600080fd5b613aae826020830160208701614c36565b600060208284031215614cb157600080fd5b815167ffffffffffffffff80821115614cc957600080fd5b908301906101408286031215614cde57600080fd5b614ce66148dc565b614cef83614c15565b8152614cfd60208401614c20565b6020820152614d0e60408401614c20565b6040820152614d1f60608401614c15565b6060820152614d3060808401614c15565b6080820152614d4160a08401614c15565b60a082015260c083015160c082015260e083015160e0820152610100614d68818501614c2b565b908201526101208381015183811115614d8057600080fd5b614d8c88828701614c5a565b918301919091525095945050505050565b60008151808452614db5816020860160208601614c36565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006101406020830151614e1b602086018261ffff169052565b506040830151614e31604086018261ffff169052565b506060830151614e59606086018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151614e81608086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614ea960a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015160c085015260e083015160e085015261010080840151614ed88287018265ffffffffffff169052565b5050610120808401518282870152614ef283870182614d9d565b9695505050505050565b604081526000614f0f6040830185614de7565b828103602084015283518152602084015160406020830152614ef26040830182614d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c3157610c31614f34565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614fab57600080fd5b83018035915067ffffffffffffffff821115614fc657600080fd5b602001915036819003821315614fdb57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150d5576150d5614f34565b5060010190565b61ffff828116828216039080821115613b5157613b51614f34565b8082028115828204841417610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615173577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561518a57600080fd5b81518015158114610c5e57600080fd5b80516dffffffffffffffffffffffffffff811681146148a857600080fd5b6000806000606084860312156151cd57600080fd5b6151d68461519a565b92506151e46020850161519a565b9150604084015163ffffffff811681146151fd57600080fd5b809150509250925092565b60006020828403121561521a57600080fd5b5051919050565b80820180821115610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561527657600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036152b8576152b8614f34565b5060000390565b602081526000610c5e6020830184614de7565b6000602082840312156152e457600080fd5b8151610c5e816149f1565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615362610180840182614d9d565b905082810360e08401526153768186614d9d565b905082810361010084015261538b8185614d9d565b9c9b505050505050505050505050565b600082516153ad818460208701614c36565b9190910192915050565b602081526000610c5e6020830184614d9d56fea26469706673582212204eecdc76d361ea4a608ec1291a66f39b61f591d844e03c8f4164adb5e8c419c464736f6c63430008130033", + "numDeployments": 7, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"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\":\"InvalidSgReceiveSrcAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSgReceiverSender\",\"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\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"bytes\",\"name\":\"_srcAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountLD\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sgReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"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\":\"warpLinkEngagePermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{\"sgReceive(uint16,bytes,uint256,address,uint256,bytes)\":{\"notice\":\"Cross-chain callback from Stargate The tokens have already been received by this contract, `t.payer` is set to this contract before `sgReceive` is called by the router. The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the same message more than once. The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the Stargate composer be compromised, an attacker can drain this contract. If the payload can not be decoded, tokens are left in this contract. If execution runs out of gas, tokens are left in this contract. If an error occurs during engage, such as insufficient output amount, tokens are refunded to the recipient. See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\"}},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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';\\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\\n bytes payload;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n address paramTokenIn;\\n uint256 paramAmountIn;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint48 paramDeadline;\\n uint256 amount;\\n address payer;\\n address token;\\n /**\\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\\n */\\n uint256 usePermit;\\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 if (t.usePermit == 1) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\\n }\\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 if (t.usePermit == 1) {\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\\n }\\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 if (t.usePermit == 1) {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(\\n t.payer,\\n params.pools[0],\\n (uint160)(t.amount),\\n t.token\\n );\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\\n }\\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({\\n payer: t.payer,\\n token: t.token,\\n amount: t.amount,\\n usePermit: t.usePermit\\n })\\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({\\n payer: t.payer,\\n token: tokenIn,\\n amount: t.amount,\\n usePermit: t.usePermit\\n })\\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 if (t.usePermit == 1) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\\n }\\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 useEth: isFromEth || isToEth,\\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 * Cross-chain callback from Stargate\\n *\\n * The tokens have already been received by this contract, `t.payer` is set to this contract\\n * before `sgReceive` is called by the router.\\n *\\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\\n * same message more than once.\\n *\\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\\n * Stargate composer be compromised, an attacker can drain this contract.\\n *\\n * If the payload can not be decoded, tokens are left in this contract.\\n * If execution runs out of gas, tokens are left in this contract.\\n *\\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\\n * to the recipient.\\n *\\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\\n */\\n function sgReceive(\\n uint16, // _srcChainId\\n bytes memory _srcAddress,\\n uint256, // _nonce\\n address _token,\\n uint256 amountLD,\\n bytes memory payload\\n ) external {\\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\\n revert InvalidSgReceiverSender();\\n }\\n\\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\\n // From https://ethereum.stackexchange.com/a/50528\\n address srcAddress;\\n\\n assembly {\\n srcAddress := mload(add(_srcAddress, 20))\\n }\\n\\n if (srcAddress != address(this)) {\\n // NOTE: This assumes that this contract is deployed at the same address on every chain\\n revert InvalidSgReceiveSrcAddress();\\n }\\n\\n Params memory params = abi.decode(payload, (Params));\\n\\n if (params.tokenIn == address(0)) {\\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\\n // otherwise because `_token` may be different on this chain\\n _token = address(0);\\n }\\n\\n try\\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\\n Params({\\n partner: params.partner,\\n feeBps: params.feeBps,\\n slippageBps: params.slippageBps,\\n recipient: params.recipient,\\n tokenIn: _token,\\n tokenOut: params.tokenOut,\\n amountIn: amountLD,\\n amountOut: params.amountOut,\\n deadline: params.deadline,\\n commands: params.commands\\n })\\n )\\n {} catch {\\n // Refund tokens to the recipient\\n if (_token == address(0)) {\\n payable(params.recipient).transfer(amountLD);\\n } else {\\n IERC20(_token).safeTransfer(params.recipient, amountLD);\\n }\\n }\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\\n * in this function.\\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 * - dstGasForCall (uint32)\\n * - tokenOut (address) when `dstGasForCall` > 0\\n * - amountOut (uint256) when `dstGasForCall` > 0\\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n params.dstGasForCall = stream.readUint32();\\n\\n if (params.dstGasForCall > 0) {\\n // NOTE: `amountIn` is left as zero\\n Params memory destParams;\\n destParams.partner = t.paramPartner;\\n destParams.feeBps = t.paramFeeBps;\\n destParams.slippageBps = t.paramSlippageBps;\\n destParams.recipient = t.paramRecipient;\\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\\n // the same address as on this chain\\n destParams.tokenIn = t.token;\\n destParams.tokenOut = stream.readAddress();\\n destParams.amountOut = stream.readUint256();\\n destParams.deadline = t.paramDeadline;\\n destParams.commands = stream.readBytes();\\n params.payload = abi.encode(destParams);\\n }\\n\\n if (t.token != t.paramTokenIn) {\\n if (params.payload.length == 0) {\\n // If the tokens are being delivered directly to the recipient without a second\\n // WarpLink engage, the fee is charged on this chain\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibStarVault.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n }\\n\\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\\n\\n if (t.token != address(0)) {\\n if (t.payer != address(this)) {\\n if (t.usePermit == 1) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n t.payer,\\n address(this),\\n (uint160)(t.amount),\\n t.token\\n );\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\\n }\\n\\n // Update the payer to this contract\\n // TODO: Is this value ever read?\\n t.payer = address(this);\\n }\\n\\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\\n IERC20(t.token).forceApprove(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\\n t.amount\\n );\\n }\\n\\n t.jumped = 1;\\n\\n // Swap on the composer if there is a payload, else the router\\n IStargateRouter(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\\n ).swap{\\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\\n }({\\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\\n // more on the other chain. It also assumes the tokens are of nearly equal value\\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: params.dstGasForCall,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n // NOTE: This assumes the contract is deployed at the same address on every chain.\\n // If this is not the case, a new param needs to be added with the next WarpLink address\\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\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\\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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function warpLinkEngagePermit(\\n Params calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n TransientState memory t;\\n t.paramPartner = params.partner;\\n t.paramFeeBps = params.feeBps;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.usePermit = 1;\\n\\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 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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0xafd9df86ea5bc03ea83d33890bbbe7e383f84bec96e5b67dd99e7d717bc9bcb3\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\\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 error InvalidSgReceiverSender();\\n error InvalidSgReceiveSrcAddress();\\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 calldata params) external payable;\\n\\n function warpLinkEngagePermit(\\n Params calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n}\\n\",\"keccak256\":\"0x0eff4788d9f45d72b6a05f34f1e8236a6f9d76a4778396d9a53c66ec04ebf726\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IStargateReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\n\\ninterface IStargateReceiver {\\n function sgReceive(\\n uint16 _srcChainId, // the remote chainId sending the tokens\\n bytes memory _srcAddress, // the remote Bridge address\\n uint256 _nonce,\\n address _token, // the token contract on the local chain\\n uint256 amountLD, // the qty of local _token contract tokens\\n bytes memory payload\\n ) external;\\n}\\n\",\"keccak256\":\"0x7fd06c09139156a4f09a77eac28e453a1d2041a8cf01a108fc875c65192cb637\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50615c3880620000216000396000f3fe6080604052600436106100345760003560e01c8063a703fc4014610039578063ab8236f31461004e578063dcc455511461006e575b600080fd5b61004c610047366004615184565b610081565b005b34801561005a57600080fd5b5061004c610069366004615368565b6106c6565b61004c61007c366004615405565b6109ac565b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152906100fd9084018461543a565b73ffffffffffffffffffffffffffffffffffffffff1681526101256040840160208501615457565b61ffff16602082015261013e6060840160408501615457565b61ffff1660c0820152610157608084016060850161543a565b73ffffffffffffffffffffffffffffffffffffffff16604082015261018260a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0840135608083015260e084013560a08301526101c490840160408501615457565b61ffff1660c08201526101df61012084016101008501615488565b65ffffffffffff1660e082015260c083013561010082015261020760a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff9081166101408301526001610160830152336101208301819052346101a08401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e08101909152921691632b67b570919080606081018061028a60a08b0160808c0161543a565b73ffffffffffffffffffffffffffffffffffffffff908116825260c08b01351660208201526040016102c46101208b016101008c01615488565b65ffffffffffff908116825289351660209182015290825230908201526040016102f661012089016101008a01615488565b65ffffffffffff16905261030d60208701876154a5565b6040518563ffffffff1660e01b815260040161032c9493929190615511565b600060405180830381600087803b15801561034657600080fd5b505af115801561035a573d6000803e3d6000fd5b5050505060006103ae8480610120019061037491906154a5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f4192505050565b90506103ba8183610f5b565b610100810151610140820151919350906103da60c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043e576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61045b60e08701356104566060890160408a01615457565b611140565b821015610494576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361018001516001036104a957505050505050565b6104e86104b9602088018861543a565b6104c960c0890160a08a0161543a565b6104d960408a0160208b01615457565b61ffff168960e001358661116e565b915081600003610524576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661059a5761054f608087016060880161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610594573d6000803e3d6000fd5b506105cb565b6105cb6105ad608088016060890161543a565b73ffffffffffffffffffffffffffffffffffffffff83169084611227565b6101a084015115610609576101a0840151604051339180156108fc02916000818181858888f19350505050158015610607573d6000803e3d6000fd5b505b61061960c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff1661063f60a088016080890161543a565b73ffffffffffffffffffffffffffffffffffffffff16610662602089018961543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c00135866040516106b6929190918252602082015260400190565b60405180910390a4505050505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461078d576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906107a39190615662565b608081015190915073ffffffffffffffffffffffffffffffffffffffff166107ca57600094505b3063dcc4555173ffffffffffffffffffffffffffffffffffffffff8716156107f35760006107f5565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff1681526020018561012001518152506040518363ffffffff1660e01b81526004016108e191906157aa565b6000604051808303818588803b1580156108fa57600080fd5b505af19350505050801561090c575060015b6109a25773ffffffffffffffffffffffffffffffffffffffff851661097b57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610975573d6000803e3d6000fd5b506109a2565b60608101516109a29073ffffffffffffffffffffffffffffffffffffffff87169086611227565b5050505050505050565b6109be61012082016101008301615488565b65ffffffffffff164211156109ff576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082015290610a7b9083018361543a565b73ffffffffffffffffffffffffffffffffffffffff168152610aa36040830160208401615457565b61ffff166020820152610abc6060830160408401615457565b61ffff1660c0820152610ad5608083016060840161543a565b73ffffffffffffffffffffffffffffffffffffffff166040820152610b0060a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0830135608083015260e083013560a0830152610b4290830160408401615457565b61ffff1660c0820152610b5d61012083016101008401615488565b65ffffffffffff1660e082015260c0820135610100820152610b8560a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff166101408201526000610bb360a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1603610c2c578160c00135341015610c0c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c1a60c0830135346158dc565b6101a082015230610120820152610c3b565b33610120820152346101a08201525b6000610c4e6103746101208501856154a5565b9050610c5a8183610f5b565b61010081015161014082015191935090610c7a60c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cde576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cf660e08601356104566060880160408901615457565b821015610d2f576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836101800151600103610d43575050505050565b610d82610d53602087018761543a565b610d6360c0880160a0890161543a565b610d736040890160208a01615457565b61ffff168860e001358661116e565b915081600003610dbe576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e3457610de9608086016060870161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610e2e573d6000803e3d6000fd5b50610e47565b610e476105ad608087016060880161543a565b6101a084015115610e85576101a0840151604051339180156108fc02916000818181858888f19350505050158015610e83573d6000803e3d6000fd5b505b610e9560c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ebb60a087016080880161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ede602088018861543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38860c0013586604051610f32929190918252602082015260400190565b60405180910390a45050505050565b604080518082019091528181528151909101602082015290565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000610fde8480516001018051915290565b60ff16905060005b818110156111345760006110008680516001018051915290565b60ff1690506001810361101d5761101685611300565b9450611121565b6002810361102e57611016856114d0565b600381036110405761101686866117f2565b60048103611052576110168686611e2a565b600581036110645761101686866121c1565b600681036110765761101686866129e3565b60078103611088576110168686612f20565b6008810361109a576110168686613471565b600981036110ef576110ad6001846158dc565b82146110e5576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61101686866138fd565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061112c816158ef565b915050610fe6565b50829150505b92915050565b600061271061114f8382615927565b61115d9061ffff1685615942565b6111679190615988565b9392505050565b60006107d08411156111b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156111c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156111fd5760646032840204611200565b60005b9050808303838214611218576112188a8a8484614125565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112fb9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526141ed565b505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140808201839052610160820183905261018082018390526101a0820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff16156113e5576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014611439576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b1580156114b057600080fd5b505af11580156114c4573d6000803e3d6000fd5b50959695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146115be576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff811630148015906115ec57306101208601525b6000610140860152801561175a578461016001516001036116b057600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b5050505061175a565b82546101008601516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015611734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175891906159c3565b505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916117b79160040190815260200190565b600060405180830381600087803b1580156117d157600080fd5b505af11580156117e5573d6000803e3d6000fd5b5096979650505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff166118b5576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff909116036119aa576119a5816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b611ad8565b826101600151600103611a90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015611a7357600080fd5b505af1158015611a87573d6000803e3d6000fd5b50505050611ad0565b611ad0836101200151826020015185610100015186610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208401525b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151611b7e57905b606083015161010086015161ffff6127109283031691840290820290810190830281611bac57611bac615959565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c469190615a53565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8560400151611c7c57876101000151611c7f565b60005b8660400151611c8f576000611c96565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015611d0057600080fd5b505af1158015611d14573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190615a53565b905081811080611dca5750610100870151611dc79083615a6c565b81105b15611e01576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000611ead8480516001018051915290565b60ff1690506000836101000151905060006002831015611ef9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561218c576000611f146001886158dc565b8210611f205785611f51565b612710611f338b80516002018051915290565b61ffff168a6101000151611f479190615942565b611f519190615988565b905085811115611f8d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f9781876158dc565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610120808201838152610140808401858152610160850186905261018085018690526101a08501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d01511690915290965061203e8b82610f5b565b905080610180015160010361207f576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361209c5780610120015193508061014001519450612170565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614612106576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614612170576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008101516121809087615a6c565b95505050600101611eff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261225660405180606001604052806060815260200160608152602001606081525090565b60006122688580516001018051915290565b60ff169050612278816001615a6c565b67ffffffffffffffff81111561229057612290615202565b6040519080825280602002602001820160405280156122b9578160200160208202803683370190505b5080835261014085015181519091906000906122d7576122d7615a7f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561237057855160140180519087528351612333836001615a6c565b8151811061234357612343615a7f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612314565b5061237b8582614360565b602083015261238a8582614402565b60408301528151805160009190839081106123a7576123a7615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615a53565b9050600061246284604001518761010001518660000151876020015161448b565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff16036124f4576124ef84602001516000815181106124b6576124b6615a7f565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b61265f565b8561016001516001036125fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061256057612560615a7f565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b81526004016125c6949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b50505050612657565b612657866101200151856020015160008151811061261d5761261d615a7f565b602002602001015188610100015189610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208701525b60005b83811015612863576000612677826001615a6c565b905060008660000151828151811061269157612691615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16876000015184815181106126c5576126c5615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106126ef5760006126f2565b60015b90506000600288600001515161270891906158dc565b84106127145730612733565b8760200151838151811061272a5761272a615a7f565b60200260200101515b90508760200151848151811061274b5761274b615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836127925786858151811061278557612785615a7f565b6020026020010151612795565b60005b846127a15760006127bc565b8786815181106127b3576127b3615a7f565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561283c57600080fd5b505af1158015612850573d6000803e3d6000fd5b5050600190950194506126629350505050565b5060008460000151848151811061287c5761287c615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129169190615a53565b9050816001835161292791906158dc565b8151811061293757612937615a7f565b6020026020010151876101000181815250508281108061296557506101008701516129629084615a6c565b81105b1561299c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518051859081106129b0576129b0615a7f565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015261014084015116612afe576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190615a53565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff16109050612c376040518060800160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018761016001518152506146c0565b8015612d1b5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d029190615aae565b91505080612d0f90615ad2565b61010087015250612e03565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def9190615aae565b509050612dfb81615ad2565b610100870152505b612e0b61484f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615a53565b905082811080612ebb5750610100860151612eb89084615a6c565b81105b15612ef2576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a0810191909152612fb560405180606001604052806060815260200160608152602001606081525090565b6000612fc78580516001018051915290565b60ff169050612fd68582614360565b8252612fe28582614360565b60208301528151600090612ff76001846158dc565b8151811061300757613007615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190615a53565b905060005b8381101561337957600081156130e55785516130c86001846158dc565b815181106130d8576130d8615a7f565b60200260200101516130ec565b8761014001515b90508560000151828151811061310457613104615a7f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516080810182526101008d015181526101208d01518416948101949094529184169183018290526101608b015160608401521190613170906146c0565b8260000361318057306101208a01525b60008760200151848151811061319857613198615a7f565b602002602001015190508115613282576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615aae565b9150508061327690615ad2565b6101008c015250613366565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561332e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133529190615aae565b50905061335e81615ad2565b6101008c0152505b61336e61484f565b5050506001016130ab565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156133ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134109190615a53565b90508181108061342e575061010087015161342b9083615a6c565b81105b15613465576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146136fe578461016001516001036136ba577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561369d57600080fd5b505af11580156136b1573d6000803e3d6000fd5b505050506136f6565b6136f68561012001513087610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208601525b60008161379b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137969190615a53565b61379d565b475b9050826137dd576137dd846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166148af9092919063ffffffff16565b61382284608001518560a001518660200151866137fb576000613802565b8961010001515b886040015189606001518c610100015160008b8061381d57508a5b61499f565b6000826138bf5784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ba9190615a53565b6138c1565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506138eb82826158dc565b61010088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526139a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613b31576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff16610100820152845160208082018051909201018652610120820152604051613afc9082906020016157aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613c4357806080015151600003613ba55782516101408401516020850151610100860151613b9e93929161ffff16908061116e565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38660800151876101000151604051613c3a929190918252602082015260400190565b60405180910390a45b613c558360a001518460c00151611140565b8361010001511015613c93576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff918216911615613ecd5761012084015173ffffffffffffffffffffffffffffffffffffffff163014613e1f57836101600151600103613ddb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015613dbe57600080fd5b505af1158015613dd2573d6000803e3d6000fd5b50505050613e17565b613e178461012001513086610100015187610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208501525b613ecd826080015151600014613e355781613ea4565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea49190615b0a565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff1691906148af565b600161018085015260808201515115613ee65780613f55565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f559190615b0a565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff1614613fb457856101a00151613fca565b856101a00151866101000151613fca9190615a6c565b8451602086015160408701516101008a015160c08b0151309190613fef908290611140565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c608001515111614035578d60400151614037565b305b604051602001614072919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b1683526140e29998979695949392600401615b27565b6000604051808303818588803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b505060006101a088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b600061424f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614e9b9092919063ffffffff16565b905080516000148061427057508080602001905181019061427091906159c3565b6112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016111ac565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261435a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611279565b50505050565b60608167ffffffffffffffff81111561437b5761437b615202565b6040519080825280602002602001820160405280156143a4578160200160208202803683370190505b50905060005b828110156143fb57835160140180519085528282815181106143ce576143ce615a7f565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016143aa565b5092915050565b60608167ffffffffffffffff81111561441d5761441d615202565b604051908082528060200260200182016040528015614446578160200160208202803683370190505b50905060005b828110156143fb578351600201805190855282828151811061447057614470615a7f565b61ffff9092166020928302919091019091015260010161444c565b805182516060919067ffffffffffffffff8111156144ab576144ab615202565b6040519080825280602002602001820160405280156144d4578160200160208202803683370190505b50915084826000815181106144eb576144eb615a7f565b60200260200101818152505060005b818110156146b657600085828151811061451657614516615a7f565b602002602001015190506000868360016145309190615a6c565b8151811061454057614540615a7f565b60200260200101519050600089848151811061455e5761455e615a7f565b60200260200101516127106145739190615927565b61ffff16905060008088868151811061458e5761458e615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156145e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146049190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561465f57905b828b0282612710020181848d02028161467a5761467a615959565b049a508a8861468a886001615a6c565b8151811061469a5761469a615a7f565b60209081029190910101525050600190930192506144fa915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361471e576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036148ad576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261493b8482614eb2565b61435a5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526149959085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611279565b61435a84826141ed565b8860ff16600103614acd578715614a58576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015614a3a57600080fd5b505af1158015614a4e573d6000803e3d6000fd5b5050505050614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614a21565b8860ff16600203614c0d578715614b98576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015614b6d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190614b929190615a53565b50614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614b4f565b8860ff16600303614dae578715614c8b576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614b4f565b8015614d05576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614b4f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015614d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b929190615a53565b8860ff16600403614e5e578715614df1576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614a21565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6060614eaa8484600085614f73565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614edc9190615bd3565b6000604051808303816000865af19150503d8060008114614f19576040519150601f19603f3d011682016040523d82523d6000602084013e614f1e565b606091505b5091509150818015614f48575080511580614f48575080806020019051810190614f4891906159c3565b8015614f6a575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b606082471015615005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016111ac565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161502e9190615bd3565b60006040518083038185875af1925050503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b50915091506150818783838761508c565b979650505050505050565b6060831561512257825160000361511b5773ffffffffffffffffffffffffffffffffffffffff85163b61511b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016111ac565b5081614eaa565b614eaa83838151156151375781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac9190615bef565b6000610140828403121561517e57600080fd5b50919050565b6000806040838503121561519757600080fd5b823567ffffffffffffffff808211156151af57600080fd5b6151bb8683870161516b565b935060208501359150808211156151d157600080fd5b508301604081860312156151e457600080fd5b809150509250929050565b61ffff811681146151ff57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561525557615255615202565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156152a2576152a2615202565b604052919050565b600067ffffffffffffffff8211156152c4576152c4615202565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261530157600080fd5b813561531461530f826152aa565b61525b565b81815284602083860101111561532957600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146151ff57600080fd5b60008060008060008060c0878903121561538157600080fd5b863561538c816151ef565b9550602087013567ffffffffffffffff808211156153a957600080fd5b6153b58a838b016152f0565b965060408901359550606089013591506153ce82615346565b9093506080880135925060a088013590808211156153eb57600080fd5b506153f889828a016152f0565b9150509295509295509295565b60006020828403121561541757600080fd5b813567ffffffffffffffff81111561542e57600080fd5b614eaa8482850161516b565b60006020828403121561544c57600080fd5b813561116781615346565b60006020828403121561546957600080fd5b8135611167816151ef565b65ffffffffffff811681146151ff57600080fd5b60006020828403121561549a57600080fd5b813561116781615474565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154da57600080fd5b83018035915067ffffffffffffffff8211156154f557600080fd5b60200191503681900382131561550a57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b80516155de81615346565b919050565b80516155de816151ef565b80516155de81615474565b60005b838110156156145781810151838201526020016155fc565b50506000910152565b600082601f83011261562e57600080fd5b815161563c61530f826152aa565b81815284602083860101111561565157600080fd5b614eaa8260208301602087016155f9565b60006020828403121561567457600080fd5b815167ffffffffffffffff8082111561568c57600080fd5b9083019061014082860312156156a157600080fd5b6156a9615231565b6156b2836155d3565b81526156c0602084016155e3565b60208201526156d1604084016155e3565b60408201526156e2606084016155d3565b60608201526156f3608084016155d3565b608082015261570460a084016155d3565b60a082015260c083015160c082015260e083015160e082015261010061572b8185016155ee565b90820152610120838101518381111561574357600080fd5b61574f8882870161561d565b918301919091525095945050505050565b600081518084526157788160208601602086016155f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526157d160208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516157e8604084018261ffff169052565b50604083015161ffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c083015160e083015260e08301516101008181850152808501519150506101206158938185018365ffffffffffff169052565b840151610140848101529050614eaa610160840182615760565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561113a5761113a6158ad565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615920576159206158ad565b5060010190565b61ffff8281168282160390808211156143fb576143fb6158ad565b808202811582820484141761113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156159d557600080fd5b8151801515811461116757600080fd5b80516dffffffffffffffffffffffffffff811681146155de57600080fd5b600080600060608486031215615a1857600080fd5b615a21846159e5565b9250615a2f602085016159e5565b9150604084015163ffffffff81168114615a4857600080fd5b809150509250925092565b600060208284031215615a6557600080fd5b5051919050565b8082018082111561113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215615ac157600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b0357615b036158ad565b5060000390565b600060208284031215615b1c57600080fd5b815161116781615346565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615b9a610180840182615760565b905082810360e0840152615bae8186615760565b9050828103610100840152615bc38185615760565b9c9b505050505050505050505050565b60008251615be58184602087016155f9565b9190910192915050565b602081526000611167602083018461576056fea26469706673582212202ce6a8f21a153c83c150806f9ce2e260656621d27c2de20b34fdaa1dbce5be3f64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c8063a703fc4014610039578063ab8236f31461004e578063dcc455511461006e575b600080fd5b61004c610047366004615184565b610081565b005b34801561005a57600080fd5b5061004c610069366004615368565b6106c6565b61004c61007c366004615405565b6109ac565b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152906100fd9084018461543a565b73ffffffffffffffffffffffffffffffffffffffff1681526101256040840160208501615457565b61ffff16602082015261013e6060840160408501615457565b61ffff1660c0820152610157608084016060850161543a565b73ffffffffffffffffffffffffffffffffffffffff16604082015261018260a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0840135608083015260e084013560a08301526101c490840160408501615457565b61ffff1660c08201526101df61012084016101008501615488565b65ffffffffffff1660e082015260c083013561010082015261020760a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff9081166101408301526001610160830152336101208301819052346101a08401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e08101909152921691632b67b570919080606081018061028a60a08b0160808c0161543a565b73ffffffffffffffffffffffffffffffffffffffff908116825260c08b01351660208201526040016102c46101208b016101008c01615488565b65ffffffffffff908116825289351660209182015290825230908201526040016102f661012089016101008a01615488565b65ffffffffffff16905261030d60208701876154a5565b6040518563ffffffff1660e01b815260040161032c9493929190615511565b600060405180830381600087803b15801561034657600080fd5b505af115801561035a573d6000803e3d6000fd5b5050505060006103ae8480610120019061037491906154a5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f4192505050565b90506103ba8183610f5b565b610100810151610140820151919350906103da60c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043e576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61045b60e08701356104566060890160408a01615457565b611140565b821015610494576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361018001516001036104a957505050505050565b6104e86104b9602088018861543a565b6104c960c0890160a08a0161543a565b6104d960408a0160208b01615457565b61ffff168960e001358661116e565b915081600003610524576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661059a5761054f608087016060880161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610594573d6000803e3d6000fd5b506105cb565b6105cb6105ad608088016060890161543a565b73ffffffffffffffffffffffffffffffffffffffff83169084611227565b6101a084015115610609576101a0840151604051339180156108fc02916000818181858888f19350505050158015610607573d6000803e3d6000fd5b505b61061960c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff1661063f60a088016080890161543a565b73ffffffffffffffffffffffffffffffffffffffff16610662602089018961543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c00135866040516106b6929190918252602082015260400190565b60405180910390a4505050505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461078d576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906107a39190615662565b608081015190915073ffffffffffffffffffffffffffffffffffffffff166107ca57600094505b3063dcc4555173ffffffffffffffffffffffffffffffffffffffff8716156107f35760006107f5565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff1681526020018561012001518152506040518363ffffffff1660e01b81526004016108e191906157aa565b6000604051808303818588803b1580156108fa57600080fd5b505af19350505050801561090c575060015b6109a25773ffffffffffffffffffffffffffffffffffffffff851661097b57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610975573d6000803e3d6000fd5b506109a2565b60608101516109a29073ffffffffffffffffffffffffffffffffffffffff87169086611227565b5050505050505050565b6109be61012082016101008301615488565b65ffffffffffff164211156109ff576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082015290610a7b9083018361543a565b73ffffffffffffffffffffffffffffffffffffffff168152610aa36040830160208401615457565b61ffff166020820152610abc6060830160408401615457565b61ffff1660c0820152610ad5608083016060840161543a565b73ffffffffffffffffffffffffffffffffffffffff166040820152610b0060a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0830135608083015260e083013560a0830152610b4290830160408401615457565b61ffff1660c0820152610b5d61012083016101008401615488565b65ffffffffffff1660e082015260c0820135610100820152610b8560a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff166101408201526000610bb360a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1603610c2c578160c00135341015610c0c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c1a60c0830135346158dc565b6101a082015230610120820152610c3b565b33610120820152346101a08201525b6000610c4e6103746101208501856154a5565b9050610c5a8183610f5b565b61010081015161014082015191935090610c7a60c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cde576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cf660e08601356104566060880160408901615457565b821015610d2f576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836101800151600103610d43575050505050565b610d82610d53602087018761543a565b610d6360c0880160a0890161543a565b610d736040890160208a01615457565b61ffff168860e001358661116e565b915081600003610dbe576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e3457610de9608086016060870161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610e2e573d6000803e3d6000fd5b50610e47565b610e476105ad608087016060880161543a565b6101a084015115610e85576101a0840151604051339180156108fc02916000818181858888f19350505050158015610e83573d6000803e3d6000fd5b505b610e9560c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ebb60a087016080880161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ede602088018861543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38860c0013586604051610f32929190918252602082015260400190565b60405180910390a45050505050565b604080518082019091528181528151909101602082015290565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000610fde8480516001018051915290565b60ff16905060005b818110156111345760006110008680516001018051915290565b60ff1690506001810361101d5761101685611300565b9450611121565b6002810361102e57611016856114d0565b600381036110405761101686866117f2565b60048103611052576110168686611e2a565b600581036110645761101686866121c1565b600681036110765761101686866129e3565b60078103611088576110168686612f20565b6008810361109a576110168686613471565b600981036110ef576110ad6001846158dc565b82146110e5576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61101686866138fd565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061112c816158ef565b915050610fe6565b50829150505b92915050565b600061271061114f8382615927565b61115d9061ffff1685615942565b6111679190615988565b9392505050565b60006107d08411156111b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156111c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156111fd5760646032840204611200565b60005b9050808303838214611218576112188a8a8484614125565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112fb9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526141ed565b505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140808201839052610160820183905261018082018390526101a0820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff16156113e5576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014611439576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b1580156114b057600080fd5b505af11580156114c4573d6000803e3d6000fd5b50959695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146115be576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff811630148015906115ec57306101208601525b6000610140860152801561175a578461016001516001036116b057600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b5050505061175a565b82546101008601516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015611734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175891906159c3565b505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916117b79160040190815260200190565b600060405180830381600087803b1580156117d157600080fd5b505af11580156117e5573d6000803e3d6000fd5b5096979650505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff166118b5576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff909116036119aa576119a5816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b611ad8565b826101600151600103611a90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015611a7357600080fd5b505af1158015611a87573d6000803e3d6000fd5b50505050611ad0565b611ad0836101200151826020015185610100015186610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208401525b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151611b7e57905b606083015161010086015161ffff6127109283031691840290820290810190830281611bac57611bac615959565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c469190615a53565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8560400151611c7c57876101000151611c7f565b60005b8660400151611c8f576000611c96565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015611d0057600080fd5b505af1158015611d14573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190615a53565b905081811080611dca5750610100870151611dc79083615a6c565b81105b15611e01576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000611ead8480516001018051915290565b60ff1690506000836101000151905060006002831015611ef9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561218c576000611f146001886158dc565b8210611f205785611f51565b612710611f338b80516002018051915290565b61ffff168a6101000151611f479190615942565b611f519190615988565b905085811115611f8d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f9781876158dc565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610120808201838152610140808401858152610160850186905261018085018690526101a08501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d01511690915290965061203e8b82610f5b565b905080610180015160010361207f576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361209c5780610120015193508061014001519450612170565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614612106576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614612170576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008101516121809087615a6c565b95505050600101611eff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261225660405180606001604052806060815260200160608152602001606081525090565b60006122688580516001018051915290565b60ff169050612278816001615a6c565b67ffffffffffffffff81111561229057612290615202565b6040519080825280602002602001820160405280156122b9578160200160208202803683370190505b5080835261014085015181519091906000906122d7576122d7615a7f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561237057855160140180519087528351612333836001615a6c565b8151811061234357612343615a7f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612314565b5061237b8582614360565b602083015261238a8582614402565b60408301528151805160009190839081106123a7576123a7615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615a53565b9050600061246284604001518761010001518660000151876020015161448b565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff16036124f4576124ef84602001516000815181106124b6576124b6615a7f565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b61265f565b8561016001516001036125fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061256057612560615a7f565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b81526004016125c6949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b50505050612657565b612657866101200151856020015160008151811061261d5761261d615a7f565b602002602001015188610100015189610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208701525b60005b83811015612863576000612677826001615a6c565b905060008660000151828151811061269157612691615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16876000015184815181106126c5576126c5615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106126ef5760006126f2565b60015b90506000600288600001515161270891906158dc565b84106127145730612733565b8760200151838151811061272a5761272a615a7f565b60200260200101515b90508760200151848151811061274b5761274b615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836127925786858151811061278557612785615a7f565b6020026020010151612795565b60005b846127a15760006127bc565b8786815181106127b3576127b3615a7f565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561283c57600080fd5b505af1158015612850573d6000803e3d6000fd5b5050600190950194506126629350505050565b5060008460000151848151811061287c5761287c615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129169190615a53565b9050816001835161292791906158dc565b8151811061293757612937615a7f565b6020026020010151876101000181815250508281108061296557506101008701516129629084615a6c565b81105b1561299c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518051859081106129b0576129b0615a7f565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015261014084015116612afe576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190615a53565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff16109050612c376040518060800160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018761016001518152506146c0565b8015612d1b5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d029190615aae565b91505080612d0f90615ad2565b61010087015250612e03565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def9190615aae565b509050612dfb81615ad2565b610100870152505b612e0b61484f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615a53565b905082811080612ebb5750610100860151612eb89084615a6c565b81105b15612ef2576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a0810191909152612fb560405180606001604052806060815260200160608152602001606081525090565b6000612fc78580516001018051915290565b60ff169050612fd68582614360565b8252612fe28582614360565b60208301528151600090612ff76001846158dc565b8151811061300757613007615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190615a53565b905060005b8381101561337957600081156130e55785516130c86001846158dc565b815181106130d8576130d8615a7f565b60200260200101516130ec565b8761014001515b90508560000151828151811061310457613104615a7f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516080810182526101008d015181526101208d01518416948101949094529184169183018290526101608b015160608401521190613170906146c0565b8260000361318057306101208a01525b60008760200151848151811061319857613198615a7f565b602002602001015190508115613282576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615aae565b9150508061327690615ad2565b6101008c015250613366565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561332e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133529190615aae565b50905061335e81615ad2565b6101008c0152505b61336e61484f565b5050506001016130ab565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156133ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134109190615a53565b90508181108061342e575061010087015161342b9083615a6c565b81105b15613465576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146136fe578461016001516001036136ba577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561369d57600080fd5b505af11580156136b1573d6000803e3d6000fd5b505050506136f6565b6136f68561012001513087610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208601525b60008161379b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137969190615a53565b61379d565b475b9050826137dd576137dd846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166148af9092919063ffffffff16565b61382284608001518560a001518660200151866137fb576000613802565b8961010001515b886040015189606001518c610100015160008b8061381d57508a5b61499f565b6000826138bf5784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ba9190615a53565b6138c1565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506138eb82826158dc565b61010088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526139a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613b31576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff16610100820152845160208082018051909201018652610120820152604051613afc9082906020016157aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613c4357806080015151600003613ba55782516101408401516020850151610100860151613b9e93929161ffff16908061116e565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38660800151876101000151604051613c3a929190918252602082015260400190565b60405180910390a45b613c558360a001518460c00151611140565b8361010001511015613c93576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff918216911615613ecd5761012084015173ffffffffffffffffffffffffffffffffffffffff163014613e1f57836101600151600103613ddb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015613dbe57600080fd5b505af1158015613dd2573d6000803e3d6000fd5b50505050613e17565b613e178461012001513086610100015187610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208501525b613ecd826080015151600014613e355781613ea4565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea49190615b0a565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff1691906148af565b600161018085015260808201515115613ee65780613f55565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f559190615b0a565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff1614613fb457856101a00151613fca565b856101a00151866101000151613fca9190615a6c565b8451602086015160408701516101008a015160c08b0151309190613fef908290611140565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c608001515111614035578d60400151614037565b305b604051602001614072919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b1683526140e29998979695949392600401615b27565b6000604051808303818588803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b505060006101a088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b600061424f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614e9b9092919063ffffffff16565b905080516000148061427057508080602001905181019061427091906159c3565b6112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016111ac565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261435a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611279565b50505050565b60608167ffffffffffffffff81111561437b5761437b615202565b6040519080825280602002602001820160405280156143a4578160200160208202803683370190505b50905060005b828110156143fb57835160140180519085528282815181106143ce576143ce615a7f565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016143aa565b5092915050565b60608167ffffffffffffffff81111561441d5761441d615202565b604051908082528060200260200182016040528015614446578160200160208202803683370190505b50905060005b828110156143fb578351600201805190855282828151811061447057614470615a7f565b61ffff9092166020928302919091019091015260010161444c565b805182516060919067ffffffffffffffff8111156144ab576144ab615202565b6040519080825280602002602001820160405280156144d4578160200160208202803683370190505b50915084826000815181106144eb576144eb615a7f565b60200260200101818152505060005b818110156146b657600085828151811061451657614516615a7f565b602002602001015190506000868360016145309190615a6c565b8151811061454057614540615a7f565b60200260200101519050600089848151811061455e5761455e615a7f565b60200260200101516127106145739190615927565b61ffff16905060008088868151811061458e5761458e615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156145e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146049190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561465f57905b828b0282612710020181848d02028161467a5761467a615959565b049a508a8861468a886001615a6c565b8151811061469a5761469a615a7f565b60209081029190910101525050600190930192506144fa915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361471e576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036148ad576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261493b8482614eb2565b61435a5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526149959085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611279565b61435a84826141ed565b8860ff16600103614acd578715614a58576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015614a3a57600080fd5b505af1158015614a4e573d6000803e3d6000fd5b5050505050614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614a21565b8860ff16600203614c0d578715614b98576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015614b6d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190614b929190615a53565b50614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614b4f565b8860ff16600303614dae578715614c8b576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614b4f565b8015614d05576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614b4f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015614d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b929190615a53565b8860ff16600403614e5e578715614df1576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614a21565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6060614eaa8484600085614f73565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614edc9190615bd3565b6000604051808303816000865af19150503d8060008114614f19576040519150601f19603f3d011682016040523d82523d6000602084013e614f1e565b606091505b5091509150818015614f48575080511580614f48575080806020019051810190614f4891906159c3565b8015614f6a575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b606082471015615005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016111ac565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161502e9190615bd3565b60006040518083038185875af1925050503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b50915091506150818783838761508c565b979650505050505050565b6060831561512257825160000361511b5773ffffffffffffffffffffffffffffffffffffffff85163b61511b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016111ac565b5081614eaa565b614eaa83838151156151375781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac9190615bef565b6000610140828403121561517e57600080fd5b50919050565b6000806040838503121561519757600080fd5b823567ffffffffffffffff808211156151af57600080fd5b6151bb8683870161516b565b935060208501359150808211156151d157600080fd5b508301604081860312156151e457600080fd5b809150509250929050565b61ffff811681146151ff57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561525557615255615202565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156152a2576152a2615202565b604052919050565b600067ffffffffffffffff8211156152c4576152c4615202565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261530157600080fd5b813561531461530f826152aa565b61525b565b81815284602083860101111561532957600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146151ff57600080fd5b60008060008060008060c0878903121561538157600080fd5b863561538c816151ef565b9550602087013567ffffffffffffffff808211156153a957600080fd5b6153b58a838b016152f0565b965060408901359550606089013591506153ce82615346565b9093506080880135925060a088013590808211156153eb57600080fd5b506153f889828a016152f0565b9150509295509295509295565b60006020828403121561541757600080fd5b813567ffffffffffffffff81111561542e57600080fd5b614eaa8482850161516b565b60006020828403121561544c57600080fd5b813561116781615346565b60006020828403121561546957600080fd5b8135611167816151ef565b65ffffffffffff811681146151ff57600080fd5b60006020828403121561549a57600080fd5b813561116781615474565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154da57600080fd5b83018035915067ffffffffffffffff8211156154f557600080fd5b60200191503681900382131561550a57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b80516155de81615346565b919050565b80516155de816151ef565b80516155de81615474565b60005b838110156156145781810151838201526020016155fc565b50506000910152565b600082601f83011261562e57600080fd5b815161563c61530f826152aa565b81815284602083860101111561565157600080fd5b614eaa8260208301602087016155f9565b60006020828403121561567457600080fd5b815167ffffffffffffffff8082111561568c57600080fd5b9083019061014082860312156156a157600080fd5b6156a9615231565b6156b2836155d3565b81526156c0602084016155e3565b60208201526156d1604084016155e3565b60408201526156e2606084016155d3565b60608201526156f3608084016155d3565b608082015261570460a084016155d3565b60a082015260c083015160c082015260e083015160e082015261010061572b8185016155ee565b90820152610120838101518381111561574357600080fd5b61574f8882870161561d565b918301919091525095945050505050565b600081518084526157788160208601602086016155f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526157d160208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516157e8604084018261ffff169052565b50604083015161ffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c083015160e083015260e08301516101008181850152808501519150506101206158938185018365ffffffffffff169052565b840151610140848101529050614eaa610160840182615760565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561113a5761113a6158ad565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615920576159206158ad565b5060010190565b61ffff8281168282160390808211156143fb576143fb6158ad565b808202811582820484141761113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156159d557600080fd5b8151801515811461116757600080fd5b80516dffffffffffffffffffffffffffff811681146155de57600080fd5b600080600060608486031215615a1857600080fd5b615a21846159e5565b9250615a2f602085016159e5565b9150604084015163ffffffff81168114615a4857600080fd5b809150509250925092565b600060208284031215615a6557600080fd5b5051919050565b8082018082111561113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215615ac157600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b0357615b036158ad565b5060000390565b600060208284031215615b1c57600080fd5b815161116781615346565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615b9a610180840182615760565b905082810360e0840152615bae8186615760565b9050828103610100840152615bc38185615760565b9c9b505050505050505050505050565b60008251615be58184602087016155f9565b9190910192915050565b602081526000611167602083018461576056fea26469706673582212202ce6a8f21a153c83c150806f9ce2e260656621d27c2de20b34fdaa1dbce5be3f64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/bsc/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json b/packages/hardhat/deployments/bsc/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json new file mode 100644 index 00000000..cf1aa121 --- /dev/null +++ b/packages/hardhat/deployments/bsc/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json @@ -0,0 +1,170 @@ +{ + "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" + }, + "@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * Perform the swap with tokens already moved to this contract\n */\n function curveExactInputSingleInternal(\n ExactInputSingleParams calldata params\n ) internal returns (uint256 amountOut) {\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 LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n useEth: params.tokenIn == address(0) || isToEth,\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function curveExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (params.tokenIn == address(0)) {\n revert PermitForEthToken();\n }\n\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 return curveExactInputSingleInternal(params);\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\n }\n\n return curveExactInputSingleInternal(params);\n }\n}\n" + }, + "contracts/facets/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract Stargate is IStargate {\n using SafeERC20 for IERC20;\n\n /**\n * Jump tokens with Stargate with input tokens already moved to this contract\n */\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.token,\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n // NOTE: This lookup is spending 319 gas\n IStargateRouter stargateRouter = IStargateRouter(\n LibWarp.state().stargateComposer.stargateRouter()\n );\n\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\n\n unchecked {\n stargateRouter.swap{value: msg.value}({\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\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\n }\n }\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable {\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.token,\n amount: 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 // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n uint160(params.amountIn),\n params.token\n );\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\n // Transfer tokens from the sender to this contract\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n address(0),\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n unchecked {\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\n _dstChainId: params.dstChainId,\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * NOTE: The tokens must already have been moved to the first pool\n */\n function uniswapV2LikeExactInputSingleInternal(\n ExactInputSingleParams memory params\n ) internal returns (uint256 amountOut) {\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : params.tokenIn,\n isToEth ? address(0) : params.tokenOut,\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\n }\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 the pool\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pool,\n (uint160)(params.amountIn),\n params.tokenIn\n );\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputInternal(\n ExactInputParams calldata params\n ) internal returns (uint256 amountOut) {\n LibWarp.State storage s = LibWarp.state();\n\n address[] memory tokens = params.tokens;\n uint256 poolLength = params.pools.length;\n bool isFromEth = tokens[0] == address(0);\n bool isToEth = tokens[poolLength] == address(0);\n\n if (isFromEth) {\n tokens[0] = address(s.weth);\n }\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : tokens[0],\n isToEth ? address(0) : tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\n } else {\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\n }\n\n return uniswapV2LikeExactInputInternal(params);\n }\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n // Permit tokens / set allowance\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n\n return uniswapV2LikeExactInputInternal(params);\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 {LibStarVault} from '../libraries/LibStarVault.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\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /**\n * NOTE: The tokens must already have been transferred to the pool\n */\n function uniswapV2ExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n address pair\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address tokenIn = params.tokenIn == address(0) ? address(s.weth) : params.tokenIn;\n address tokenOut = params.tokenOut == address(0) ? address(s.weth) : params.tokenOut;\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (tokenIn > 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 InsufficientOutputAmount();\n }\n\n bool zeroForOne = tokenIn < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.tokenOut == address(0)) {\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn == address(0) ? address(s.weth) : params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\n if (params.tokenIn == address(0)) {\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(address(s.weth)).safeTransfer(pair, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, pair, params.amountIn);\n }\n\n return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\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 return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n /**\n * NOTE: The tokens must already have been transferred to the first pool\n *\n * The path should be rewritten so address(0) is replaced by the WETH address\n */\n function uniswapV2ExactInputInternal(\n ExactInputParams calldata params,\n address[] memory path,\n address[] memory pairs,\n uint256[] memory amounts\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\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 = path[index] < path[indexPlusOne] ? true : false;\n address to = index < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH. 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(path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.path[0],\n params.path[pathLengthMinusOne],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[0] == address(0)) {\n // From ETH\n path[0] = address(s.weth);\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\n }\n\n if (params.path[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer WETH tokens to the first pool\n IERC20(path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n IERC20(path[0]).safeTransferFrom(msg.sender, pairs[0], params.amountIn);\n }\n\n return uniswapV2ExactInputInternal(params, path, pairs, amounts);\n }\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: 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 return uniswapV2ExactInputInternal(params, path, pairs, amounts);\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 if (callback.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n } else {\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\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 /**\n * NOTE: None of these arguments can be trusted\n */\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * KyperSwap V2 callback\n * NOTE: None of these arguments can be trusted\n */\n function swapCallback(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 {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n bool isFromEth = params.tokenIn == address(0);\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\n\n address tokenOut = params.tokenOut == address(0)\n ? address(LibWarp.state().weth)\n : params.tokenOut;\n\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\n\n bool zeroForOne = tokenIn < tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: tokenIn,\n amount: params.amountIn,\n usePermit: usePermit\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokenOut == address(0)) {\n // To ETH, unwrap WETH\n // TODO: This is read twice. Compare gas usage\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH, wrap it\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\n }\n\n function uniswapV3LikeExactInputInternal(\n ExactInputParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n uint256 poolLength = params.pools.length;\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\n address[] memory tokens = params.tokens;\n\n if (params.tokens[0] == address(0)) {\n tokens[0] = address(LibWarp.state().weth);\n }\n\n if (params.tokens[poolLength] == address(0)) {\n tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: payer,\n token: tokens[index],\n amount: amountOut,\n usePermit: usePermit\n })\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokens[poolLength] == address(0)) {\n // To ETH, unwrap\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.tokens[0],\n params.tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH, wrap it\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n }\n\n return uniswapV3LikeExactInputInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputInternal(params, 1);\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 {LibStarVault} from '../libraries/LibStarVault.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';\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\n bytes payload;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n address paramTokenIn;\n uint256 paramAmountIn;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint48 paramDeadline;\n uint256 amount;\n address payer;\n address token;\n /**\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\n */\n uint256 usePermit;\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 if (t.usePermit == 1) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\n }\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 if (t.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\n }\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(\n t.payer,\n params.pools[0],\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\n }\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({\n payer: t.payer,\n token: t.token,\n amount: t.amount,\n usePermit: t.usePermit\n })\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({\n payer: t.payer,\n token: tokenIn,\n amount: t.amount,\n usePermit: t.usePermit\n })\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\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 useEth: isFromEth || isToEth,\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 * Cross-chain callback from Stargate\n *\n * The tokens have already been received by this contract, `t.payer` is set to this contract\n * before `sgReceive` is called by the router.\n *\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\n * same message more than once.\n *\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\n * Stargate composer be compromised, an attacker can drain this contract.\n *\n * If the payload can not be decoded, tokens are left in this contract.\n * If execution runs out of gas, tokens are left in this contract.\n *\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\n * to the recipient.\n *\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\n */\n function sgReceive(\n uint16, // _srcChainId\n bytes memory _srcAddress,\n uint256, // _nonce\n address _token,\n uint256 amountLD,\n bytes memory payload\n ) external {\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\n revert InvalidSgReceiverSender();\n }\n\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\n // From https://ethereum.stackexchange.com/a/50528\n address srcAddress;\n\n assembly {\n srcAddress := mload(add(_srcAddress, 20))\n }\n\n if (srcAddress != address(this)) {\n // NOTE: This assumes that this contract is deployed at the same address on every chain\n revert InvalidSgReceiveSrcAddress();\n }\n\n Params memory params = abi.decode(payload, (Params));\n\n if (params.tokenIn == address(0)) {\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\n // otherwise because `_token` may be different on this chain\n _token = address(0);\n }\n\n try\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\n Params({\n partner: params.partner,\n feeBps: params.feeBps,\n slippageBps: params.slippageBps,\n recipient: params.recipient,\n tokenIn: _token,\n tokenOut: params.tokenOut,\n amountIn: amountLD,\n amountOut: params.amountOut,\n deadline: params.deadline,\n commands: params.commands\n })\n )\n {} catch {\n // Refund tokens to the recipient\n if (_token == address(0)) {\n payable(params.recipient).transfer(amountLD);\n } else {\n IERC20(_token).safeTransfer(params.recipient, amountLD);\n }\n }\n }\n\n /**\n * Jump to another chain using the Stargate bridge\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\n * in this function.\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 * - dstGasForCall (uint32)\n * - tokenOut (address) when `dstGasForCall` > 0\n * - amountOut (uint256) when `dstGasForCall` > 0\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n params.dstGasForCall = stream.readUint32();\n\n if (params.dstGasForCall > 0) {\n // NOTE: `amountIn` is left as zero\n Params memory destParams;\n destParams.partner = t.paramPartner;\n destParams.feeBps = t.paramFeeBps;\n destParams.slippageBps = t.paramSlippageBps;\n destParams.recipient = t.paramRecipient;\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\n // the same address as on this chain\n destParams.tokenIn = t.token;\n destParams.tokenOut = stream.readAddress();\n destParams.amountOut = stream.readUint256();\n destParams.deadline = t.paramDeadline;\n destParams.commands = stream.readBytes();\n params.payload = abi.encode(destParams);\n }\n\n if (t.token != t.paramTokenIn) {\n if (params.payload.length == 0) {\n // If the tokens are being delivered directly to the recipient without a second\n // WarpLink engage, the fee is charged on this chain\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\n // is never charged\n t.amount = LibStarVault.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n }\n\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n t.payer,\n address(this),\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\n\n // Update the payer to this contract\n // TODO: Is this value ever read?\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\n IERC20(t.token).forceApprove(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\n t.amount\n );\n }\n\n t.jumped = 1;\n\n // Swap on the composer if there is a payload, else the router\n IStargateRouter(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\n ).swap{\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\n }({\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\n // more on the other chain. It also assumes the tokens are of nearly equal value\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: params.dstGasForCall,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n // NOTE: This assumes the contract is deployed at the same address on every chain.\n // If this is not the case, a new param needs to be added with the next WarpLink address\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\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\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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable {\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.usePermit = 1;\n\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 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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\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(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy,\n bool use_eth\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\n// Kind 4, uint256s with no return value\n// Example v0.2.15, \"Pool for USDT/BTC/ETH or similar\"\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\ninterface ICurvePoolKind4 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\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/IStargateComposer.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\nimport {IStargateRouter} from './IStargateRouter.sol';\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateComposer is IStargateRouter {\n function stargateRouter() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/IStargateReceiver.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\n\ninterface IStargateReceiver {\n function sgReceive(\n uint16 _srcChainId, // the remote chainId sending the tokens\n bytes memory _srcAddress, // the remote Bridge address\n uint256 _nonce,\n address _token, // the token contract on the local chain\n uint256 amountLD, // the qty of local _token contract tokens\n bytes memory payload\n ) 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n /**\n * A function expecting a permit was used when the input token is ETH\n */\n error PermitForEthToken();\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 curveExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/ILibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibCurve {\n error UnhandledPoolKind();\n}\n" + }, + "contracts/interfaces/ILibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n}\n" + }, + "contracts/interfaces/ILibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n}\n" + }, + "contracts/interfaces/ILibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n}\n" + }, + "contracts/interfaces/IStargate.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\n\ninterface IStargate is ILibStarVault {\n error InsufficientEthValue();\n\n struct JumpTokenParams {\n address token;\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n struct JumpNativeParams {\n /**\n * The amount in is passed to distinguish the amount to bridge from the fee\n */\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable;\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Like is ILibStarVault, ILibWarp {\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 ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Router is ILibStarVault, ILibWarp {\n error EthTransferFailed();\n error ZeroAmountOut();\n error IncorrectEthValue();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\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 error InvalidSgReceiverSender();\n error InvalidSgReceiveSrcAddress();\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 calldata params) external payable;\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable;\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibCurve\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 bool useEth\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 if (useEth) {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\n } else {\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\n }\n } else if (kind == 4) {\n if (underlying) {\n revert UnhandledPoolKind();\n } else {\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * NOTE: Events and errors must be copied to ILibStarVault\n */\nlibrary LibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n\n struct State {\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 uint256 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n /**\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\n * removed to save gas.\n */\n unchecked {\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\n\n assembly {\n s.slot := storagePosition\n }\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 protocolFee\n ) internal {\n State storage s = state();\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit Fee(partner, token, partnerFee, protocolFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint256 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 feeProtocol = feeTotal - feePartner;\n\n if (feeProtocol > 0) {\n registerCollectedFee(partner, token, feePartner, feeProtocol);\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\n/**\n * NOTE: Events and errors must be copied to ILibUniV3Like\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 * Whether to use a permit transfer (0 or 1)\n */\n uint256 usePermit;\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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibWarp\n */\nlibrary LibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateComposer stargateComposer;\n }\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\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 dd76c502..7133a48f 100644 --- a/packages/hardhat/deployments/mainnet/Curve.json +++ b/packages/hardhat/deployments/mainnet/Curve.json @@ -1,5 +1,5 @@ { - "address": "0xAEDbF8b5033d9a325c5d57E59a78C5fADe013c1D", + "address": "0xbf0bF02AD7A83b8AFA73e8d47276be9462f92965", "abi": [ { "inputs": [], @@ -38,6 +38,11 @@ "name": "InsufficientOutputAmount", "type": "error" }, + { + "inputs": [], + "name": "PermitForEthToken", + "type": "error" + }, { "inputs": [], "name": "UnhandledPoolKind", @@ -116,6 +121,97 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "curveExactInputSingle", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -213,7 +309,7 @@ "type": "tuple" } ], - "name": "curveExactInputSingle", + "name": "curveExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -225,28 +321,28 @@ "type": "function" } ], - "transactionHash": "0x36832f22a36b02d11c22b98652171fcf4998712041b9939fcbb435808c019ea8", + "transactionHash": "0xe33d888f0a4f175470234608ae14baea79ace03343dafc2fba3c9eb2f3a3d568", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xAEDbF8b5033d9a325c5d57E59a78C5fADe013c1D", - "transactionIndex": 14, - "gasUsed": "1361652", + "contractAddress": "0xbf0bF02AD7A83b8AFA73e8d47276be9462f92965", + "transactionIndex": 95, + "gasUsed": "1468928", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x2674ec022292d4bf800e60f043bb1e0654433d66c91db7d5a84d5bd18ae3f060", - "transactionHash": "0x36832f22a36b02d11c22b98652171fcf4998712041b9939fcbb435808c019ea8", + "blockHash": "0xb6e6bb269b83453936cb78cec987e09337a3228f247110f7001eb7a6a1e4ec13", + "transactionHash": "0xe33d888f0a4f175470234608ae14baea79ace03343dafc2fba3c9eb2f3a3d568", "logs": [], - "blockNumber": 18439224, - "cumulativeGasUsed": "4271698", + "blockNumber": 18511204, + "cumulativeGasUsed": "10378681", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 12, - "solcInputHash": "ebf955869df0dfecc3a0eb12547e8afc", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 useEth: params.tokenIn == address(0) || isToEth,\\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0x6d796fc46a41bd9fe76ae989d273f90aa0298f993f5c77cf481f5968fad21474\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\\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\":\"0x88d6dcf171951cf8e3f3488ef5d66a953614ae48926f9ace36d58b095bf9dc84\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506117d5806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b6100366100313660046113ad565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906114ed565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff9091169161066b565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b90890189611506565b6040518563ffffffff1660e01b815260040161026a9493929190611572565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b6103cc856101800151866101a001518760600151348961014001518a61016001518b6000015160008073ffffffffffffffffffffffffffffffffffffffff168e60e0015173ffffffffffffffffffffffffffffffffffffffff1614806103c757508a5b6107df565b60008261046d576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046891906114ed565b61046f565b475b905061047b8282611663565b935061048f86602001518760a00151610cdb565b8410156104c8576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ea8660c00151876101000151886080015161ffff16896020015188610d0b565b93508215610596576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610550576040519150601f19603f3d011682016040523d82523d6000602084013e610555565b606091505b5050905080610590576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506105ca565b6105ca86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610dc49092919063ffffffff16565b85610100015173ffffffffffffffffffffffffffffffffffffffff168660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f389600001518860405161065a929190918252602082015260400190565b60405180910390a450505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106f78482610e1f565b6107d95760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526107cf9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610ee0565b6107d98482610ee0565b50505050565b8860ff1660010361090d578715610898576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b5050505050610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610861565b8860ff16600203610a4d5787156109d8576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156109ad573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109d291906114ed565b50610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df0212490889060840161098f565b8860ff16600303610bee578715610acb576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b90889060840161098f565b8015610b45576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a40161098f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015610bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d291906114ed565b8860ff16600403610c9e578715610c31576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610861565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6000612710610cea8382611676565b610cf89061ffff1685611698565b610d0291906116af565b90505b92915050565b60006107d0841115610d52576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610d64575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610d9a5760646032840204610d9d565b60005b9050808303838214610db557610db58a8a8484610fef565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e1a9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161074d565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e49919061170e565b6000604051808303816000865af19150503d8060008114610e86576040519150601f19603f3d011682016040523d82523d6000602084013e610e8b565b606091505b5091509150818015610eb5575080511580610eb5575080806020019051810190610eb5919061172a565b8015610ed7575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166110b79092919063ffffffff16565b9050805160001480610f63575080806020019051810190610f63919061172a565b610e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d49565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60606110c684846000856110ce565b949350505050565b606082471015611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d49565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611189919061170e565b60006040518083038185875af1925050503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b50915091506111dc878383876111e7565b979650505050505050565b6060831561127d5782516000036112765773ffffffffffffffffffffffffffffffffffffffff85163b611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d49565b50816110c6565b6110c683838151156112925781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d49919061174e565b6040516101c0810167ffffffffffffffff81118282101715611311577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133b57600080fd5b919050565b803561ffff8116811461133b57600080fd5b803565ffffffffffff8116811461133b57600080fd5b803560ff8116811461133b57600080fd5b801515811461138757600080fd5b50565b803561133b81611379565b6000604082840312156113a757600080fd5b50919050565b6000808284036101e08112156113c257600080fd5b6101c0808212156113d257600080fd5b6113da6112c6565b915084358252602085013560208301526113f660408601611317565b604083015261140760608601611317565b606083015261141860808601611340565b608083015261142960a08601611340565b60a083015261143a60c08601611317565b60c083015261144b60e08601611317565b60e083015261010061145e818701611317565b90830152610120611470868201611352565b90830152610140611482868201611368565b90830152610160611494868201611368565b908301526101806114a6868201611368565b908301526101a06114b886820161138a565b9083015290925083013567ffffffffffffffff8111156114d757600080fd5b6114e385828601611395565b9150509250929050565b6000602082840312156114ff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261153b57600080fd5b83018035915067ffffffffffffffff82111561155657600080fd5b60200191503681900382131561156b57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d0557610d05611634565b61ffff82811682821603908082111561169157611691611634565b5092915050565b8082028115828204841417610d0557610d05611634565b6000826116e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156117055781810151838201526020016116ed565b50506000910152565b600082516117208184602087016116ea565b9190910192915050565b60006020828403121561173c57600080fd5b815161174781611379565b9392505050565b602081526000825180602084015261176d8160408501602087016116ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212204f164ad9f74d85efb515fab3ce059723b15ff2d1b51c1308c6989e26aff5f0c564736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b6100366100313660046113ad565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906114ed565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff9091169161066b565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b90890189611506565b6040518563ffffffff1660e01b815260040161026a9493929190611572565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b6103cc856101800151866101a001518760600151348961014001518a61016001518b6000015160008073ffffffffffffffffffffffffffffffffffffffff168e60e0015173ffffffffffffffffffffffffffffffffffffffff1614806103c757508a5b6107df565b60008261046d576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046891906114ed565b61046f565b475b905061047b8282611663565b935061048f86602001518760a00151610cdb565b8410156104c8576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ea8660c00151876101000151886080015161ffff16896020015188610d0b565b93508215610596576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610550576040519150601f19603f3d011682016040523d82523d6000602084013e610555565b606091505b5050905080610590576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506105ca565b6105ca86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610dc49092919063ffffffff16565b85610100015173ffffffffffffffffffffffffffffffffffffffff168660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f389600001518860405161065a929190918252602082015260400190565b60405180910390a450505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106f78482610e1f565b6107d95760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526107cf9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610ee0565b6107d98482610ee0565b50505050565b8860ff1660010361090d578715610898576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b5050505050610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610861565b8860ff16600203610a4d5787156109d8576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156109ad573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109d291906114ed565b50610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df0212490889060840161098f565b8860ff16600303610bee578715610acb576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b90889060840161098f565b8015610b45576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a40161098f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015610bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d291906114ed565b8860ff16600403610c9e578715610c31576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610861565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6000612710610cea8382611676565b610cf89061ffff1685611698565b610d0291906116af565b90505b92915050565b60006107d0841115610d52576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610d64575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610d9a5760646032840204610d9d565b60005b9050808303838214610db557610db58a8a8484610fef565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e1a9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161074d565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e49919061170e565b6000604051808303816000865af19150503d8060008114610e86576040519150601f19603f3d011682016040523d82523d6000602084013e610e8b565b606091505b5091509150818015610eb5575080511580610eb5575080806020019051810190610eb5919061172a565b8015610ed7575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166110b79092919063ffffffff16565b9050805160001480610f63575080806020019051810190610f63919061172a565b610e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d49565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60606110c684846000856110ce565b949350505050565b606082471015611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d49565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611189919061170e565b60006040518083038185875af1925050503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b50915091506111dc878383876111e7565b979650505050505050565b6060831561127d5782516000036112765773ffffffffffffffffffffffffffffffffffffffff85163b611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d49565b50816110c6565b6110c683838151156112925781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d49919061174e565b6040516101c0810167ffffffffffffffff81118282101715611311577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133b57600080fd5b919050565b803561ffff8116811461133b57600080fd5b803565ffffffffffff8116811461133b57600080fd5b803560ff8116811461133b57600080fd5b801515811461138757600080fd5b50565b803561133b81611379565b6000604082840312156113a757600080fd5b50919050565b6000808284036101e08112156113c257600080fd5b6101c0808212156113d257600080fd5b6113da6112c6565b915084358252602085013560208301526113f660408601611317565b604083015261140760608601611317565b606083015261141860808601611340565b608083015261142960a08601611340565b60a083015261143a60c08601611317565b60c083015261144b60e08601611317565b60e083015261010061145e818701611317565b90830152610120611470868201611352565b90830152610140611482868201611368565b90830152610160611494868201611368565b908301526101806114a6868201611368565b908301526101a06114b886820161138a565b9083015290925083013567ffffffffffffffff8111156114d757600080fd5b6114e385828601611395565b9150509250929050565b6000602082840312156114ff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261153b57600080fd5b83018035915067ffffffffffffffff82111561155657600080fd5b60200191503681900382131561156b57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d0557610d05611634565b61ffff82811682821603908082111561169157611691611634565b5092915050565b8082028115828204841417610d0557610d05611634565b6000826116e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156117055781810151838201526020016116ed565b50506000910152565b600082516117208184602087016116ea565b9190910192915050565b60006020828403121561173c57600080fd5b815161174781611379565b9392505050565b602081526000825180602084015261176d8160408501602087016116ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212204f164ad9f74d85efb515fab3ce059723b15ff2d1b51c1308c6989e26aff5f0c564736f6c63430008130033", + "numDeployments": 13, + "solcInputHash": "b02a0ce4f8d2d52325669cdc01d21082", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermitForEthToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"name\":\"curveExactInputSingle\",\"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\":\"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\":\"curveExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}],\"PermitForEthToken()\":[{\"notice\":\"A function expecting a permit was used when the input token is ETH\"}]},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\\n * Perform the swap with tokens already moved to this contract\\n */\\n function curveExactInputSingleInternal(\\n ExactInputSingleParams calldata params\\n ) internal returns (uint256 amountOut) {\\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 LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n useEth: params.tokenIn == address(0) || isToEth,\\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function curveExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (params.tokenIn == address(0)) {\\n revert PermitForEthToken();\\n }\\n\\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 return curveExactInputSingleInternal(params);\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\\n }\\n\\n return curveExactInputSingleInternal(params);\\n }\\n}\\n\",\"keccak256\":\"0x14d74eb8ac6efa00532e5de577c6b6ca66866e6991a220986ca7733d920de561\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n /**\\n * A function expecting a permit was used when the input token is ETH\\n */\\n error PermitForEthToken();\\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 curveExactInputSinglePermit(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xd034586f038b6ea01e6ce9d6497d203ef8cc5d221884f1a6f608ce08bae51904\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506119c8806100206000396000f3fe6080604052600436106100295760003560e01c806356bf88f01461002e578063aef417b114610053575b600080fd5b61004161003c366004611598565b610066565b60405190815260200160405180910390f35b6100416100613660046115f0565b610348565b60008061007a610100850160e0860161160d565b73ffffffffffffffffffffffffffffffffffffffff16036100c7576040517f53e40ce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a6100da608085016060860161160d565b84356100ed610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff169190610430565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925273ffffffffffffffffffffffffffffffffffffffff90921691632b67b57091339190819060608201908190610174906101008c01908c0161160d565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016101ab6101408b016101208c0161164a565b65ffffffffffff908116825289351660209182015290825230908201526040016101dd61014089016101208a0161164a565b65ffffffffffff1690526101f46020870187611672565b6040518563ffffffff1660e01b815260040161021394939291906116de565b600060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505061026c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333086356102a0610100890160e08a0161160d565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561031e57600080fd5b505af1158015610332573d6000803e3d6000fd5b5050505061033f836105a4565b90505b92915050565b600061035c6101408301610120840161164a565b65ffffffffffff1642111561039d576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103b0610100840160e0850161160d565b73ffffffffffffffffffffffffffffffffffffffff1614610427576103f16103de608084016060850161160d565b83356100ed610100860160e0870161160d565b61042733308435610409610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff16929190610a43565b610342826105a4565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526104bc8482610aa1565b61059e5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526105949085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610b62565b61059e8482610b62565b50505050565b600080806105ba6101208501610100860161160d565b73ffffffffffffffffffffffffffffffffffffffff16149050600081610681576105ec6101208501610100860161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c91906117a0565b610683565b475b905061073661069a6101a0860161018087016117b9565b6106ac6101c087016101a088016117ed565b6106bc608088016060890161160d565b346106cf6101608a016101408b016117b9565b6106e16101808b016101608c016117b9565b8a6000013560008073ffffffffffffffffffffffffffffffffffffffff168d60e0016020810190610712919061160d565b73ffffffffffffffffffffffffffffffffffffffff16148061073157508a5b610c7b565b6000826107e45761074f6101208601610100870161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df91906117a0565b6107e6565b475b90506107f28282611839565b9350610811602086013561080c60c0880160a0890161184c565b611177565b84101561084a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088e61085d60e0870160c0880161160d565b61086f6101208801610100890161160d565b61087f60a0890160808a0161184c565b61ffff1688602001358861119e565b935082156109455760006108a8606087016040880161160d565b73ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146108ff576040519150601f19603f3d011682016040523d82523d6000602084013e610904565b606091505b505090508061093f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610988565b610988610958606087016040880161160d565b8561096b61012089016101008a0161160d565b73ffffffffffffffffffffffffffffffffffffffff169190611252565b61099a6101208601610100870161160d565b73ffffffffffffffffffffffffffffffffffffffff166109c1610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff166109e760e0880160c0890161160d565b60408051893581526020810189905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261059e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610512565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610acb9190611894565b6000604051808303816000865af19150503d8060008114610b08576040519150601f19603f3d011682016040523d82523d6000602084013e610b0d565b606091505b5091509150818015610b37575080511580610b37575080806020019051810190610b3791906118b0565b8015610b59575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610bc4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112a89092919063ffffffff16565b9050805160001480610be5575080806020019051810190610be591906118b0565b610c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b8860ff16600103610da9578715610d34576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015610d1657600080fd5b505af1158015610d2a573d6000803e3d6000fd5b505050505061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610cfd565b8860ff16600203610ee9578715610e74576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015610e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b5061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610e2b565b8860ff1660030361108a578715610f67576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401610e2b565b8015610fe1576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401610e2b565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015611066573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b8860ff1660040361113a5787156110cd576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610cfd565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600061271061118683826118cd565b6111949061ffff16856118ef565b61033f9190611906565b60006107d08411156111e0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d06004820152602401610c6d565b600082848111156111f2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611228576064603284020461122b565b60005b9050808303838214611243576112438a8a84846112bf565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c769084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610512565b60606112b78484600085611387565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606082471015611419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c6d565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516114429190611894565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b5091509150611495878383876114a0565b979650505050505050565b6060831561153657825160000361152f5773ffffffffffffffffffffffffffffffffffffffff85163b61152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c6d565b50816112b7565b6112b7838381511561154b5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9190611941565b60006101c0828403121561159257600080fd5b50919050565b6000806101e083850312156115ac57600080fd5b6115b6848461157f565b91506101c083013567ffffffffffffffff8111156115d357600080fd5b8301604081860312156115e557600080fd5b809150509250929050565b60006101c0828403121561160357600080fd5b61033f838361157f565b60006020828403121561161f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461164357600080fd5b9392505050565b60006020828403121561165c57600080fd5b813565ffffffffffff8116811461164357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126116a757600080fd5b83018035915067ffffffffffffffff8211156116c257600080fd5b6020019150368190038213156116d757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156117b257600080fd5b5051919050565b6000602082840312156117cb57600080fd5b813560ff8116811461164357600080fd5b80151581146117ea57600080fd5b50565b6000602082840312156117ff57600080fd5b8135611643816117dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156103425761034261180a565b60006020828403121561185e57600080fd5b813561ffff8116811461164357600080fd5b60005b8381101561188b578181015183820152602001611873565b50506000910152565b600082516118a6818460208701611870565b9190910192915050565b6000602082840312156118c257600080fd5b8151611643816117dc565b61ffff8281168282160390808211156118e8576118e861180a565b5092915050565b80820281158282048414176103425761034261180a565b60008261193c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6020815260008251806020840152611960816040850160208701611870565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202b55d2f11aa7f1395a3e9c79ad5594ecdb6d8158214c767aed2d3da3a5500d1264736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c806356bf88f01461002e578063aef417b114610053575b600080fd5b61004161003c366004611598565b610066565b60405190815260200160405180910390f35b6100416100613660046115f0565b610348565b60008061007a610100850160e0860161160d565b73ffffffffffffffffffffffffffffffffffffffff16036100c7576040517f53e40ce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a6100da608085016060860161160d565b84356100ed610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff169190610430565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925273ffffffffffffffffffffffffffffffffffffffff90921691632b67b57091339190819060608201908190610174906101008c01908c0161160d565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016101ab6101408b016101208c0161164a565b65ffffffffffff908116825289351660209182015290825230908201526040016101dd61014089016101208a0161164a565b65ffffffffffff1690526101f46020870187611672565b6040518563ffffffff1660e01b815260040161021394939291906116de565b600060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505061026c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333086356102a0610100890160e08a0161160d565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561031e57600080fd5b505af1158015610332573d6000803e3d6000fd5b5050505061033f836105a4565b90505b92915050565b600061035c6101408301610120840161164a565b65ffffffffffff1642111561039d576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103b0610100840160e0850161160d565b73ffffffffffffffffffffffffffffffffffffffff1614610427576103f16103de608084016060850161160d565b83356100ed610100860160e0870161160d565b61042733308435610409610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff16929190610a43565b610342826105a4565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526104bc8482610aa1565b61059e5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526105949085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610b62565b61059e8482610b62565b50505050565b600080806105ba6101208501610100860161160d565b73ffffffffffffffffffffffffffffffffffffffff16149050600081610681576105ec6101208501610100860161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c91906117a0565b610683565b475b905061073661069a6101a0860161018087016117b9565b6106ac6101c087016101a088016117ed565b6106bc608088016060890161160d565b346106cf6101608a016101408b016117b9565b6106e16101808b016101608c016117b9565b8a6000013560008073ffffffffffffffffffffffffffffffffffffffff168d60e0016020810190610712919061160d565b73ffffffffffffffffffffffffffffffffffffffff16148061073157508a5b610c7b565b6000826107e45761074f6101208601610100870161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df91906117a0565b6107e6565b475b90506107f28282611839565b9350610811602086013561080c60c0880160a0890161184c565b611177565b84101561084a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088e61085d60e0870160c0880161160d565b61086f6101208801610100890161160d565b61087f60a0890160808a0161184c565b61ffff1688602001358861119e565b935082156109455760006108a8606087016040880161160d565b73ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146108ff576040519150601f19603f3d011682016040523d82523d6000602084013e610904565b606091505b505090508061093f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610988565b610988610958606087016040880161160d565b8561096b61012089016101008a0161160d565b73ffffffffffffffffffffffffffffffffffffffff169190611252565b61099a6101208601610100870161160d565b73ffffffffffffffffffffffffffffffffffffffff166109c1610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff166109e760e0880160c0890161160d565b60408051893581526020810189905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261059e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610512565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610acb9190611894565b6000604051808303816000865af19150503d8060008114610b08576040519150601f19603f3d011682016040523d82523d6000602084013e610b0d565b606091505b5091509150818015610b37575080511580610b37575080806020019051810190610b3791906118b0565b8015610b59575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610bc4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112a89092919063ffffffff16565b9050805160001480610be5575080806020019051810190610be591906118b0565b610c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b8860ff16600103610da9578715610d34576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015610d1657600080fd5b505af1158015610d2a573d6000803e3d6000fd5b505050505061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610cfd565b8860ff16600203610ee9578715610e74576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015610e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b5061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610e2b565b8860ff1660030361108a578715610f67576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401610e2b565b8015610fe1576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401610e2b565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015611066573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b8860ff1660040361113a5787156110cd576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610cfd565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600061271061118683826118cd565b6111949061ffff16856118ef565b61033f9190611906565b60006107d08411156111e0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d06004820152602401610c6d565b600082848111156111f2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611228576064603284020461122b565b60005b9050808303838214611243576112438a8a84846112bf565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c769084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610512565b60606112b78484600085611387565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606082471015611419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c6d565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516114429190611894565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b5091509150611495878383876114a0565b979650505050505050565b6060831561153657825160000361152f5773ffffffffffffffffffffffffffffffffffffffff85163b61152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c6d565b50816112b7565b6112b7838381511561154b5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9190611941565b60006101c0828403121561159257600080fd5b50919050565b6000806101e083850312156115ac57600080fd5b6115b6848461157f565b91506101c083013567ffffffffffffffff8111156115d357600080fd5b8301604081860312156115e557600080fd5b809150509250929050565b60006101c0828403121561160357600080fd5b61033f838361157f565b60006020828403121561161f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461164357600080fd5b9392505050565b60006020828403121561165c57600080fd5b813565ffffffffffff8116811461164357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126116a757600080fd5b83018035915067ffffffffffffffff8211156116c257600080fd5b6020019150368190038213156116d757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156117b257600080fd5b5051919050565b6000602082840312156117cb57600080fd5b813560ff8116811461164357600080fd5b80151581146117ea57600080fd5b50565b6000602082840312156117ff57600080fd5b8135611643816117dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156103425761034261180a565b60006020828403121561185e57600080fd5b813561ffff8116811461164357600080fd5b60005b8381101561188b578181015183820152602001611873565b50506000910152565b600082516118a6818460208701611870565b9190910192915050565b6000602082840312156118c257600080fd5b8151611643816117dc565b61ffff8281168282160390808211156118e8576118e861180a565b5092915050565b80820281158282048414176103425761034261180a565b60008261193c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6020815260008251806020840152611960816040850160208701611870565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202b55d2f11aa7f1395a3e9c79ad5594ecdb6d8158214c767aed2d3da3a5500d1264736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, @@ -261,6 +357,11 @@ { "notice": "The swap fee is over the maximum allowed" } + ], + "PermitForEthToken()": [ + { + "notice": "A function expecting a permit was used when the input token is ETH" + } ] }, "kind": "user", diff --git a/packages/hardhat/deployments/mainnet/Stargate.json b/packages/hardhat/deployments/mainnet/Stargate.json index b74f54e3..94acc2ee 100644 --- a/packages/hardhat/deployments/mainnet/Stargate.json +++ b/packages/hardhat/deployments/mainnet/Stargate.json @@ -1,5 +1,5 @@ { - "address": "0xeAceEDaa6457d4464A6a07d7507205D8f878FA0F", + "address": "0x0a6c2e6bE7b2c8928e656476297F4493F22a459b", "abi": [ { "inputs": [ @@ -124,6 +124,76 @@ "stateMutability": "payable", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint160", + "name": "amountIn", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "amountOutExpected", + "type": "uint160" + }, + { + "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": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "srcPoolId", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "dstPoolId", + "type": "uint8" + } + ], + "internalType": "struct IStargate.JumpTokenParams", + "name": "params", + "type": "tuple" + } + ], + "name": "stargateJumpToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -206,34 +276,34 @@ "type": "tuple" } ], - "name": "stargateJumpToken", + "name": "stargateJumpTokenPermit", "outputs": [], "stateMutability": "payable", "type": "function" } ], - "transactionHash": "0x27e8aaa7e6928343c01c4515e2114464d171bb0da7140c50f973f591a05422cb", + "transactionHash": "0x59b83510ef9cc5215e7e93810c82537cecbb569309e716a0fa0814343b6ee212", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xeAceEDaa6457d4464A6a07d7507205D8f878FA0F", - "transactionIndex": 95, - "gasUsed": "1185014", + "contractAddress": "0x0a6c2e6bE7b2c8928e656476297F4493F22a459b", + "transactionIndex": 102, + "gasUsed": "1254580", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x245e22cff06f6f030913603cba096e83f63d276d9f028001662744fa372df045", - "transactionHash": "0x27e8aaa7e6928343c01c4515e2114464d171bb0da7140c50f973f591a05422cb", + "blockHash": "0xd7ca3e2db714aa4a43d0adcfdd3434705d2803b9b5a01abc5769a1c1eac188cb", + "transactionHash": "0x59b83510ef9cc5215e7e93810c82537cecbb569309e716a0fa0814343b6ee212", "logs": [], - "blockNumber": 18383634, - "cumulativeGasUsed": "14219898", + "blockNumber": 18511213, + "cumulativeGasUsed": "11388946", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpNativeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"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\":\"stargateJumpToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Stargate.sol\":\"Stargate\"},\"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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract Stargate is IStargate {\\n using SafeERC20 for IERC20;\\n\\n function stargateJumpToken(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.token,\\n amount: 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 // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n uint160(params.amountIn),\\n params.token\\n );\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.token,\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n // NOTE: This lookup is spending 319 gas\\n IStargateRouter stargateRouter = IStargateRouter(\\n LibWarp.state().stargateComposer.stargateRouter()\\n );\\n\\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\\n\\n unchecked {\\n stargateRouter.swap{value: msg.value}({\\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\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n address(0),\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n unchecked {\\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n}\\n\",\"keccak256\":\"0x384ff4fd006f55fd52c6532724722c9d8709db7760e8296c8a9447a19bd148f1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/IStargate.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\n\\ninterface IStargate is ILibStarVault {\\n error InsufficientEthValue();\\n\\n struct JumpTokenParams {\\n address token;\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n struct JumpNativeParams {\\n /**\\n * The amount in is passed to distinguish the amount to bridge from the fee\\n */\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n function stargateJumpToken(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\\n}\\n\",\"keccak256\":\"0x4464ecac16a3c449c8f7983ac21ba54a44ac02194baa590c480b6ffc1cddd478\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b5061148c806100206000396000f3fe6080604052600436106100295760003560e01c806329859a061461002e578063c2bee2af14610043575b600080fd5b61004161003c366004610fca565b610056565b005b610041610051366004611029565b610618565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100b760208a018a611067565b73ffffffffffffffffffffffffffffffffffffffff1681526020018860200160208101906100e59190611067565b73ffffffffffffffffffffffffffffffffffffffff16815260200161011060e08a0160c08b0161108b565b65ffffffffffff9081168252883516602091820152908252309082015260400161014060e0880160c0890161108b565b65ffffffffffff16905261015760208601866110b3565b6040518563ffffffff1660e01b8152600401610176949392919061111f565b600060405180830381600087803b15801561019057600080fd5b505af11580156101a4573d6000803e3d6000fd5b505050506101cf7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633306102006040870160208801611067565b61020d6020880188611067565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561028b57600080fd5b505af115801561029f573d6000803e3d6000fd5b50505050600061032d8360e00160208101906102bb9190611067565b6102c86020860186611067565b6102d860c0870160a088016111e1565b61ffff166102ec6040880160208901611067565b73ffffffffffffffffffffffffffffffffffffffff166103126040890160208a01611067565b73ffffffffffffffffffffffffffffffffffffffff16610905565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190611205565b905061041581836103f86020880188611067565b73ffffffffffffffffffffffffffffffffffffffff1691906109be565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc34610444610120880161010089016111e1565b61045661014089016101208a01611222565b6104686101608a016101408b01611222565b33888061047b60408e0160208f01611067565b73ffffffffffffffffffffffffffffffffffffffff16036104a260608e0160408f01611067565b73ffffffffffffffffffffffffffffffffffffffff16116104c4576000610534565b6105348a8d60200160208101906104db9190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d60400160208101906105059190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d608001602081019061052f91906111e1565b610aee565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508d60600160208101906105739190611067565b6040516020016105ae919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016105e09897969594939291906112b3565b6000604051808303818588803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050505050505050565b6106256020820182611067565b73ffffffffffffffffffffffffffffffffffffffff16341015610674576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106cf61068960e0840160c08501611067565b600061069b60a08601608087016111e1565b61ffff166106ac6020870187611067565b73ffffffffffffffffffffffffffffffffffffffff166103126020880188611067565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261071d6020860186611067565b73ffffffffffffffffffffffffffffffffffffffff16033403610747610100860160e087016111e1565b61075961012087016101008801611222565b61076b61014088016101208901611222565b33878061077b60208c018c611067565b73ffffffffffffffffffffffffffffffffffffffff16036107a260408c0160208d01611067565b73ffffffffffffffffffffffffffffffffffffffff16116107c4576000610823565b610823896107d560208d018d611067565b73ffffffffffffffffffffffffffffffffffffffff16036107fc60408d0160208e01611067565b73ffffffffffffffffffffffffffffffffffffffff160361052f60808d0160608e016111e1565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b60400160208101906108629190611067565b60405160200161089d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016108cf9897969594939291906112b3565b6000604051808303818588803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b50505050505050565b60006107d084111561094c576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561095e575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109945760646032840204610997565b60005b90508083038382146109af576109af8a8a8484610b1e565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610a4a8482610be6565b610ae8576040805173ffffffffffffffffffffffffffffffffffffffff8516602482015260006044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610ade908590610ca7565b610ae88482610ca7565b50505050565b6000612710610afd8382611391565b610b0b9061ffff16856113b3565b610b1591906113ca565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c109190611405565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611421565b8015610c9e575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610dbb9092919063ffffffff16565b9050805160001480610d2a575080806020019051810190610d2a9190611421565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610943565b505050565b6060610dca8484600085610dd2565b949350505050565b606082471015610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610943565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610e8d9190611405565b60006040518083038185875af1925050503d8060008114610eca576040519150601f19603f3d011682016040523d82523d6000602084013e610ecf565b606091505b5091509150610ee087838387610eeb565b979650505050505050565b60608315610f81578251600003610f7a5773ffffffffffffffffffffffffffffffffffffffff85163b610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b5081610dca565b610dca8383815115610f965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109439190611443565b600080828403610180811215610fdf57600080fd5b61016080821215610fef57600080fd5b849350830135905067ffffffffffffffff81111561100c57600080fd5b83016040818603121561101e57600080fd5b809150509250929050565b6000610140828403121561103c57600080fd5b50919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461106457600080fd5b50565b60006020828403121561107957600080fd5b813561108481611042565b9392505050565b60006020828403121561109d57600080fd5b813565ffffffffffff8116811461108457600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110e857600080fd5b83018035915067ffffffffffffffff82111561110357600080fd5b60200191503681900382131561111857600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156111f357600080fd5b813561ffff8116811461108457600080fd5b60006020828403121561121757600080fd5b815161108481611042565b60006020828403121561123457600080fd5b813560ff8116811461108457600080fd5b60005b83811015611260578181015183820152602001611248565b50506000910152565b60008151808452611281816020860160208601611245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c08401528451818401525060208401516101408301526040840151606061016084015261132c610180840182611269565b905082810360e08401526113408185611269565b838103610100850152600081529050602081019b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156113ac576113ac611362565b5092915050565b8082028115828204841417610b1857610b18611362565b600082611400577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251611417818460208701611245565b9190910192915050565b60006020828403121561143357600080fd5b8151801515811461108457600080fd5b602081526000610b15602083018461126956fea2646970667358221220fd4949e43a56ae6a92fdbb921568c2bc2a7013da24304d0b873ce9c5e7515c0264736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806329859a061461002e578063c2bee2af14610043575b600080fd5b61004161003c366004610fca565b610056565b005b610041610051366004611029565b610618565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100b760208a018a611067565b73ffffffffffffffffffffffffffffffffffffffff1681526020018860200160208101906100e59190611067565b73ffffffffffffffffffffffffffffffffffffffff16815260200161011060e08a0160c08b0161108b565b65ffffffffffff9081168252883516602091820152908252309082015260400161014060e0880160c0890161108b565b65ffffffffffff16905261015760208601866110b3565b6040518563ffffffff1660e01b8152600401610176949392919061111f565b600060405180830381600087803b15801561019057600080fd5b505af11580156101a4573d6000803e3d6000fd5b505050506101cf7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633306102006040870160208801611067565b61020d6020880188611067565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561028b57600080fd5b505af115801561029f573d6000803e3d6000fd5b50505050600061032d8360e00160208101906102bb9190611067565b6102c86020860186611067565b6102d860c0870160a088016111e1565b61ffff166102ec6040880160208901611067565b73ffffffffffffffffffffffffffffffffffffffff166103126040890160208a01611067565b73ffffffffffffffffffffffffffffffffffffffff16610905565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190611205565b905061041581836103f86020880188611067565b73ffffffffffffffffffffffffffffffffffffffff1691906109be565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc34610444610120880161010089016111e1565b61045661014089016101208a01611222565b6104686101608a016101408b01611222565b33888061047b60408e0160208f01611067565b73ffffffffffffffffffffffffffffffffffffffff16036104a260608e0160408f01611067565b73ffffffffffffffffffffffffffffffffffffffff16116104c4576000610534565b6105348a8d60200160208101906104db9190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d60400160208101906105059190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d608001602081019061052f91906111e1565b610aee565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508d60600160208101906105739190611067565b6040516020016105ae919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016105e09897969594939291906112b3565b6000604051808303818588803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050505050505050565b6106256020820182611067565b73ffffffffffffffffffffffffffffffffffffffff16341015610674576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106cf61068960e0840160c08501611067565b600061069b60a08601608087016111e1565b61ffff166106ac6020870187611067565b73ffffffffffffffffffffffffffffffffffffffff166103126020880188611067565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261071d6020860186611067565b73ffffffffffffffffffffffffffffffffffffffff16033403610747610100860160e087016111e1565b61075961012087016101008801611222565b61076b61014088016101208901611222565b33878061077b60208c018c611067565b73ffffffffffffffffffffffffffffffffffffffff16036107a260408c0160208d01611067565b73ffffffffffffffffffffffffffffffffffffffff16116107c4576000610823565b610823896107d560208d018d611067565b73ffffffffffffffffffffffffffffffffffffffff16036107fc60408d0160208e01611067565b73ffffffffffffffffffffffffffffffffffffffff160361052f60808d0160608e016111e1565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b60400160208101906108629190611067565b60405160200161089d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016108cf9897969594939291906112b3565b6000604051808303818588803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b50505050505050565b60006107d084111561094c576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561095e575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109945760646032840204610997565b60005b90508083038382146109af576109af8a8a8484610b1e565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610a4a8482610be6565b610ae8576040805173ffffffffffffffffffffffffffffffffffffffff8516602482015260006044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610ade908590610ca7565b610ae88482610ca7565b50505050565b6000612710610afd8382611391565b610b0b9061ffff16856113b3565b610b1591906113ca565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c109190611405565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611421565b8015610c9e575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610dbb9092919063ffffffff16565b9050805160001480610d2a575080806020019051810190610d2a9190611421565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610943565b505050565b6060610dca8484600085610dd2565b949350505050565b606082471015610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610943565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610e8d9190611405565b60006040518083038185875af1925050503d8060008114610eca576040519150601f19603f3d011682016040523d82523d6000602084013e610ecf565b606091505b5091509150610ee087838387610eeb565b979650505050505050565b60608315610f81578251600003610f7a5773ffffffffffffffffffffffffffffffffffffffff85163b610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b5081610dca565b610dca8383815115610f965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109439190611443565b600080828403610180811215610fdf57600080fd5b61016080821215610fef57600080fd5b849350830135905067ffffffffffffffff81111561100c57600080fd5b83016040818603121561101e57600080fd5b809150509250929050565b6000610140828403121561103c57600080fd5b50919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461106457600080fd5b50565b60006020828403121561107957600080fd5b813561108481611042565b9392505050565b60006020828403121561109d57600080fd5b813565ffffffffffff8116811461108457600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110e857600080fd5b83018035915067ffffffffffffffff82111561110357600080fd5b60200191503681900382131561111857600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156111f357600080fd5b813561ffff8116811461108457600080fd5b60006020828403121561121757600080fd5b815161108481611042565b60006020828403121561123457600080fd5b813560ff8116811461108457600080fd5b60005b83811015611260578181015183820152602001611248565b50506000910152565b60008151808452611281816020860160208601611245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c08401528451818401525060208401516101408301526040840151606061016084015261132c610180840182611269565b905082810360e08401526113408185611269565b838103610100850152600081529050602081019b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156113ac576113ac611362565b5092915050565b8082028115828204841417610b1857610b18611362565b600082611400577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251611417818460208701611245565b9190910192915050565b60006020828403121561143357600080fd5b8151801515811461108457600080fd5b602081526000610b15602083018461126956fea2646970667358221220fd4949e43a56ae6a92fdbb921568c2bc2a7013da24304d0b873ce9c5e7515c0264736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "b02a0ce4f8d2d52325669cdc01d21082", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpNativeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"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\":\"stargateJumpTokenPermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Stargate.sol\":\"Stargate\"},\"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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract Stargate is IStargate {\\n using SafeERC20 for IERC20;\\n\\n /**\\n * Jump tokens with Stargate with input tokens already moved to this contract\\n */\\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.token,\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n // NOTE: This lookup is spending 319 gas\\n IStargateRouter stargateRouter = IStargateRouter(\\n LibWarp.state().stargateComposer.stargateRouter()\\n );\\n\\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\\n\\n unchecked {\\n stargateRouter.swap{value: msg.value}({\\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\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n\\n function stargateJumpTokenPermit(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.token,\\n amount: 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 // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n uint160(params.amountIn),\\n params.token\\n );\\n\\n stargateJumpTokenInternal(params);\\n }\\n\\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\\n // Transfer tokens from the sender to this contract\\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\\n\\n stargateJumpTokenInternal(params);\\n }\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n address(0),\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n unchecked {\\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6abe4954877eed5b5a9c473441ac11e6f505d6cedc5c1d9489960227c5fb6f84\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/IStargate.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\n\\ninterface IStargate is ILibStarVault {\\n error InsufficientEthValue();\\n\\n struct JumpTokenParams {\\n address token;\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n struct JumpNativeParams {\\n /**\\n * The amount in is passed to distinguish the amount to bridge from the fee\\n */\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\\n\\n function stargateJumpTokenPermit(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\\n}\\n\",\"keccak256\":\"0xb35bd721e5ab9f7cd120a61bdafd807dcebd1cf71f5189662697f47a1f10986c\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506115d1806100206000396000f3fe6080604052600436106100345760003560e01c80638be9f27914610039578063ba2466d41461004e578063c2bee2af14610061575b600080fd5b61004c610047366004611102565b610074565b005b61004c61005c36600461115a565b6102ce565b61004c61006f366004611177565b610330565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100d560208a018a6111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200188602001602081019061010391906111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200161012e60e08a0160c08b016111d0565b65ffffffffffff9081168252883516602091820152908252309082015260400161015e60e0880160c089016111d0565b65ffffffffffff16905261017560208601866111f8565b6040518563ffffffff1660e01b81526004016101949493929190611264565b600060405180830381600087803b1580156101ae57600080fd5b505af11580156101c2573d6000803e3d6000fd5b505050506101ed7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333061021e60408701602088016111ac565b61022b60208801886111ac565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102a957600080fd5b505af11580156102bd573d6000803e3d6000fd5b505050506102ca8261063d565b5050565b61032433306102e360408501602086016111ac565b73ffffffffffffffffffffffffffffffffffffffff1661030660208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff16929190610986565b61032d8161063d565b50565b61033d60208201826111ac565b73ffffffffffffffffffffffffffffffffffffffff1634101561038c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104026103a160e0840160c085016111ac565b60006103b360a0860160808701611326565b61ffff166103c460208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760208801886111ac565b73ffffffffffffffffffffffffffffffffffffffff16610a68565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261045060208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff1603340361047a610100860160e08701611326565b61048c6101208701610100880161134a565b61049e6101408801610120890161134a565b3387806104ae60208c018c6111ac565b73ffffffffffffffffffffffffffffffffffffffff16036104d560408c0160208d016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116104f757600061055b565b61055b8961050860208d018d6111ac565b73ffffffffffffffffffffffffffffffffffffffff160361052f60408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660808d0160608e01611326565b610b21565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b604001602081019061059a91906111ac565b6040516020016105d5919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016106079897969594939291906113db565b6000604051808303818588803b15801561062057600080fd5b505af1158015610634573d6000803e3d6000fd5b50505050505050565b60006106aa610653610100840160e085016111ac565b61066060208501856111ac565b61067060c0860160a08701611326565b61ffff1661068460408701602088016111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760408801602089016111ac565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610761919061148a565b9050610792818361077560208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff169190610b51565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc346107c161012087016101008801611326565b6107d36101408801610120890161134a565b6107e561016089016101408a0161134a565b3388806107f860408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361081f60608d0160408e016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116108415760006108a3565b6108a38a61085560408e0160208f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361087c60608e0160408f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660a08e0160808f01611326565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60600160208101906108e291906111ac565b60405160200161091d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b815260040161094f9897969594939291906113db565b6000604051808303818588803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a629085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610c3d565b50505050565b60006107d0841115610aaf576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610ac1575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610af75760646032840204610afa565b60005b9050808303838214610b1257610b128a8a8484610d51565b50505090910395945050505050565b6000612710610b3083826114d6565b610b3e9061ffff16856114f8565b610b48919061150f565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610bdd8482610e19565b610a625760405173ffffffffffffffffffffffffffffffffffffffff8416602482015260006044820152610c379085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109e0565b610a6284825b6000610c9f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610eda9092919063ffffffff16565b9050805160001480610cc0575080806020019051810190610cc0919061154a565b610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa6565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e43919061156c565b6000604051808303816000865af19150503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5091509150818015610eaf575080511580610eaf575080806020019051810190610eaf919061154a565b8015610ed1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060610ee98484600085610ef1565b949350505050565b606082471015610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fac919061156c565b60006040518083038185875af1925050503d8060008114610fe9576040519150601f19603f3d011682016040523d82523d6000602084013e610fee565b606091505b5091509150610fff8783838761100a565b979650505050505050565b606083156110a05782516000036110995773ffffffffffffffffffffffffffffffffffffffff85163b611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa6565b5081610ee9565b610ee983838151156110b55781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa69190611588565b600061016082840312156110fc57600080fd5b50919050565b600080610180838503121561111657600080fd5b61112084846110e9565b915061016083013567ffffffffffffffff81111561113d57600080fd5b83016040818603121561114f57600080fd5b809150509250929050565b6000610160828403121561116d57600080fd5b610b4883836110e9565b600061014082840312156110fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461032d57600080fd5b6000602082840312156111be57600080fd5b81356111c98161118a565b9392505050565b6000602082840312156111e257600080fd5b813565ffffffffffff811681146111c957600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261122d57600080fd5b83018035915067ffffffffffffffff82111561124857600080fd5b60200191503681900382131561125d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60006020828403121561133857600080fd5b813561ffff811681146111c957600080fd5b60006020828403121561135c57600080fd5b813560ff811681146111c957600080fd5b60005b83811015611388578181015183820152602001611370565b50506000910152565b600081518084526113a981602086016020860161136d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c084015284518184015250602084015161014083015260408401516060610160840152611454610180840182611391565b905082810360e08401526114688185611391565b838103610100850152600081529050602081019b9a5050505050505050505050565b60006020828403121561149c57600080fd5b81516111c98161118a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156114f1576114f16114a7565b5092915050565b8082028115828204841417610b4b57610b4b6114a7565b600082611545577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561155c57600080fd5b815180151581146111c957600080fd5b6000825161157e81846020870161136d565b9190910192915050565b602081526000610b48602083018461139156fea26469706673582212208328d8149ca8eb632152123f06714fc50d6667b0823eba29b328ace315d4e37464736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c80638be9f27914610039578063ba2466d41461004e578063c2bee2af14610061575b600080fd5b61004c610047366004611102565b610074565b005b61004c61005c36600461115a565b6102ce565b61004c61006f366004611177565b610330565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100d560208a018a6111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200188602001602081019061010391906111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200161012e60e08a0160c08b016111d0565b65ffffffffffff9081168252883516602091820152908252309082015260400161015e60e0880160c089016111d0565b65ffffffffffff16905261017560208601866111f8565b6040518563ffffffff1660e01b81526004016101949493929190611264565b600060405180830381600087803b1580156101ae57600080fd5b505af11580156101c2573d6000803e3d6000fd5b505050506101ed7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333061021e60408701602088016111ac565b61022b60208801886111ac565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102a957600080fd5b505af11580156102bd573d6000803e3d6000fd5b505050506102ca8261063d565b5050565b61032433306102e360408501602086016111ac565b73ffffffffffffffffffffffffffffffffffffffff1661030660208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff16929190610986565b61032d8161063d565b50565b61033d60208201826111ac565b73ffffffffffffffffffffffffffffffffffffffff1634101561038c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104026103a160e0840160c085016111ac565b60006103b360a0860160808701611326565b61ffff166103c460208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760208801886111ac565b73ffffffffffffffffffffffffffffffffffffffff16610a68565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261045060208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff1603340361047a610100860160e08701611326565b61048c6101208701610100880161134a565b61049e6101408801610120890161134a565b3387806104ae60208c018c6111ac565b73ffffffffffffffffffffffffffffffffffffffff16036104d560408c0160208d016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116104f757600061055b565b61055b8961050860208d018d6111ac565b73ffffffffffffffffffffffffffffffffffffffff160361052f60408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660808d0160608e01611326565b610b21565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b604001602081019061059a91906111ac565b6040516020016105d5919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016106079897969594939291906113db565b6000604051808303818588803b15801561062057600080fd5b505af1158015610634573d6000803e3d6000fd5b50505050505050565b60006106aa610653610100840160e085016111ac565b61066060208501856111ac565b61067060c0860160a08701611326565b61ffff1661068460408701602088016111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760408801602089016111ac565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610761919061148a565b9050610792818361077560208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff169190610b51565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc346107c161012087016101008801611326565b6107d36101408801610120890161134a565b6107e561016089016101408a0161134a565b3388806107f860408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361081f60608d0160408e016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116108415760006108a3565b6108a38a61085560408e0160208f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361087c60608e0160408f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660a08e0160808f01611326565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60600160208101906108e291906111ac565b60405160200161091d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b815260040161094f9897969594939291906113db565b6000604051808303818588803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a629085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610c3d565b50505050565b60006107d0841115610aaf576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610ac1575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610af75760646032840204610afa565b60005b9050808303838214610b1257610b128a8a8484610d51565b50505090910395945050505050565b6000612710610b3083826114d6565b610b3e9061ffff16856114f8565b610b48919061150f565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610bdd8482610e19565b610a625760405173ffffffffffffffffffffffffffffffffffffffff8416602482015260006044820152610c379085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109e0565b610a6284825b6000610c9f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610eda9092919063ffffffff16565b9050805160001480610cc0575080806020019051810190610cc0919061154a565b610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa6565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e43919061156c565b6000604051808303816000865af19150503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5091509150818015610eaf575080511580610eaf575080806020019051810190610eaf919061154a565b8015610ed1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060610ee98484600085610ef1565b949350505050565b606082471015610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fac919061156c565b60006040518083038185875af1925050503d8060008114610fe9576040519150601f19603f3d011682016040523d82523d6000602084013e610fee565b606091505b5091509150610fff8783838761100a565b979650505050505050565b606083156110a05782516000036110995773ffffffffffffffffffffffffffffffffffffffff85163b611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa6565b5081610ee9565b610ee983838151156110b55781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa69190611588565b600061016082840312156110fc57600080fd5b50919050565b600080610180838503121561111657600080fd5b61112084846110e9565b915061016083013567ffffffffffffffff81111561113d57600080fd5b83016040818603121561114f57600080fd5b809150509250929050565b6000610160828403121561116d57600080fd5b610b4883836110e9565b600061014082840312156110fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461032d57600080fd5b6000602082840312156111be57600080fd5b81356111c98161118a565b9392505050565b6000602082840312156111e257600080fd5b813565ffffffffffff811681146111c957600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261122d57600080fd5b83018035915067ffffffffffffffff82111561124857600080fd5b60200191503681900382131561125d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60006020828403121561133857600080fd5b813561ffff811681146111c957600080fd5b60006020828403121561135c57600080fd5b813560ff811681146111c957600080fd5b60005b83811015611388578181015183820152602001611370565b50506000910152565b600081518084526113a981602086016020860161136d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c084015284518184015250602084015161014083015260408401516060610160840152611454610180840182611391565b905082810360e08401526114688185611391565b838103610100850152600081529050602081019b9a5050505050505050505050565b60006020828403121561149c57600080fd5b81516111c98161118a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156114f1576114f16114a7565b5092915050565b8082028115828204841417610b4b57610b4b6114a7565b600082611545577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561155c57600080fd5b815180151581146111c957600080fd5b6000825161157e81846020870161136d565b9190910192915050565b602081526000610b48602083018461139156fea26469706673582212208328d8149ca8eb632152123f06714fc50d6667b0823eba29b328ace315d4e37464736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/UniV2LikeFacet.json b/packages/hardhat/deployments/mainnet/UniV2LikeFacet.json index 3e0ae2e9..546f0c83 100644 --- a/packages/hardhat/deployments/mainnet/UniV2LikeFacet.json +++ b/packages/hardhat/deployments/mainnet/UniV2LikeFacet.json @@ -1,5 +1,5 @@ { - "address": "0x84E7000cA725b4013062C81142FcCFc147D484Ff", + "address": "0x9E00F2f7b3bFD1d45745d7EDAf6323F2aB97Abe2", "abi": [ { "inputs": [], @@ -116,6 +116,77 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV2LikeExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -193,7 +264,83 @@ "type": "tuple" } ], - "name": "uniswapV2LikeExactInput", + "name": "uniswapV2LikeExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV2LikeExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -286,7 +433,7 @@ "type": "tuple" } ], - "name": "uniswapV2LikeExactInputSingle", + "name": "uniswapV2LikeExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -294,32 +441,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0x507bd58625d8e7a65648b5a42c530594f1971d324da4aab4ed65a34565075a45", + "transactionHash": "0x5c6eb9f889800f52292f91d31b58b2a7b6a3b4d069d4a0d12592a271ec4a330f", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x84E7000cA725b4013062C81142FcCFc147D484Ff", - "transactionIndex": 62, - "gasUsed": "2102179", + "contractAddress": "0x9E00F2f7b3bFD1d45745d7EDAf6323F2aB97Abe2", + "transactionIndex": 91, + "gasUsed": "2341137", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x8e29254f7d2b83069a13b1928073f1314e7efd89adada2a81b7f33737dd25e35", - "transactionHash": "0x507bd58625d8e7a65648b5a42c530594f1971d324da4aab4ed65a34565075a45", + "blockHash": "0xd8f9f4bd397b6290d6fd175b69fd4f0420dd5574fd9d0f391295787391ac2886", + "transactionHash": "0x5c6eb9f889800f52292f91d31b58b2a7b6a3b4d069d4a0d12592a271ec4a330f", "logs": [], - "blockNumber": 18383614, - "cumulativeGasUsed": "8280316", + "blockNumber": 18511042, + "cumulativeGasUsed": "9620724", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 11, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokens[0],\\n isToEth ? address(0) : params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x4d807156203d016fd7fe1ff2dd503972c0f07d9d8f1b0794aca4459c1ea03b7a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Like is ILibStarVault, ILibWarp {\\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\":\"0x80c9be72cf89c5673f0acfb44d672ae65e86062906042a31007a9737c9e1a3db\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612542806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611e34565b610066565b60405190815260200160405180910390f35b610041610061366004612036565b6109e7565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101949190612176565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb6121fd565b0497505061030189602001518a60a00151611569565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611599565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61222c565b6040518563ffffffff1660e01b81526004016104db9493929190612298565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b505050506101008a01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190612176565b90508481108061076b57506107688986612389565b81105b156107a2576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c48b60c001518c61010001518d6080015161ffff168e602001518d61162b565b985085156108f35787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108ad576040519150601f19603f3d011682016040523d82523d6000602084013e6108b2565b606091505b50509050806108ed576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610927565b6109278b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b85610937578a610100015161093a565b60005b73ffffffffffffffffffffffffffffffffffffffff168761095f578b60e00151610962565b60005b73ffffffffffffffffffffffffffffffffffffffff168c60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38e600001518d6040516109d1929190918252602082015260400190565b60405180910390a4505050505050505092915050565b60008260c0015165ffffffffffff16421115610a2f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1092916000918291908290610a7557610a7561239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610ac657610ac661239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610ba4578761010001518481518110610b0557610b0561239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9f9190612176565b610ba6565b475b90506000610bc889604001518a600001518b61010001518c61012001516116e4565b9050610bdc89602001518a60800151611569565b8160018351610beb91906123cb565b81518110610bfb57610bfb61239c565b60200260200101511015610c3b576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610d725788513414610c7b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b5050505050610d6d896101200151600081518110610d1b57610d1b61239c565b60200260200101518a600001518b6101000151600081518110610d4057610d4061239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b610fc7565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610de157610de161239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610e87919061222c565b6040518563ffffffff1660e01b8152600401610ea69493929190612298565b600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610f1557610f1561239c565b60200260200101518c600001518d6101000151600081518110610f3a57610f3a61239c565b60200260200101516040518563ffffffff1660e01b8152600401610f94949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610fae57600080fd5b505af1158015610fc2573d6000803e3d6000fd5b505050505b60005b858110156111d0576000610fdf826001612389565b905060008b61010001518281518110610ffa57610ffa61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c6101000151848151811061102f5761102f61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061105957600061105c565b60015b9050600060028d61010001515161107391906123cb565b841061107f573061109f565b8c610120015183815181106110965761109661239c565b60200260200101515b90508c610120015184815181106110b8576110b861239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836110ff578685815181106110f2576110f261239c565b6020026020010151611102565b60005b8461110e576000611129565b8786815181106111205761112061239c565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156111a957600080fd5b505af11580156111bd573d6000803e3d6000fd5b505060019095019450610fca9350505050565b50600089610100015186815181106111ea576111ea61239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190612176565b90508281108061129c57506112998884612389565b81105b156112d3576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113278a60e001518b610100015188815181106112f2576112f261239c565b60200260200101518c60a0015161ffff168d60200151868b8151811061131a5761131a61239c565b602002602001015161162b565b975083156114565786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611410576040519150601f19603f3d011682016040523d82523d6000602084013e611415565b606091505b5050905080611450576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611476565b6114768a60600151898c61010001518981518110610d4057610d4061239c565b8361149f5789610100015186815181106114925761149261239c565b60200260200101516114a2565b60005b73ffffffffffffffffffffffffffffffffffffffff16856114e2578a61010001516000815181106114d5576114d561239c565b60200260200101516114e5565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60e0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c604051611554929190918252602082015260400190565b60405180910390a45050505050505092915050565b600061271061157883826123de565b6115869061ffff1685612400565b6115909190612417565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611626908490611919565b505050565b60006107d0841115611672576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611684575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116ba57606460328402046116bd565b60005b90508083038382146116d5576116d58a8a8484611a28565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561170457611704611cff565b60405190808252806020026020018201604052801561172d578160200160208202803683370190505b50915084826000815181106117445761174461239c565b60200260200101818152505060005b8181101561190f57600085828151811061176f5761176f61239c565b602002602001015190506000868360016117899190612389565b815181106117995761179961239c565b6020026020010151905060008984815181106117b7576117b761239c565b60200260200101516127106117cc91906123de565b61ffff1690506000808886815181106117e7576117e761239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185d91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156118b857905b828b0282612710020181848d0202816118d3576118d36121fd565b049a508a886118e3886001612389565b815181106118f3576118f361239c565b6020908102919091010152505060019093019250611753915050565b5050949350505050565b600061197b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611af09092919063ffffffff16565b905080516000148061199c57508080602001905181019061199c9190612452565b611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611669565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611aff8484600085611b07565b949350505050565b606082471015611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611669565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bc2919061249f565b60006040518083038185875af1925050503d8060008114611bff576040519150601f19603f3d011682016040523d82523d6000602084013e611c04565b606091505b5091509150611c1587838387611c20565b979650505050505050565b60608315611cb6578251600003611caf5773ffffffffffffffffffffffffffffffffffffffff85163b611caf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611669565b5081611aff565b611aff8383815115611ccb5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166991906124bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611d5257611d52611cff565b60405290565b604051610140810167ffffffffffffffff81118282101715611d5257611d52611cff565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc357611dc3611cff565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611def57600080fd5b919050565b803561ffff81168114611def57600080fd5b803565ffffffffffff81168114611def57600080fd5b600060408284031215611e2e57600080fd5b50919050565b600080828403610180811215611e4957600080fd5b61016080821215611e5957600080fd5b611e61611d2e565b91508435825260208501356020830152611e7d60408601611dcb565b6040830152611e8e60608601611dcb565b6060830152611e9f60808601611df4565b6080830152611eb060a08601611df4565b60a0830152611ec160c08601611dcb565b60c0830152611ed260e08601611dcb565b60e0830152610100611ee5818701611dcb565b90830152610120611ef7868201611df4565b90830152610140611f09868201611e06565b9083015290925083013567ffffffffffffffff811115611f2857600080fd5b611f3485828601611e1c565b9150509250929050565b600067ffffffffffffffff821115611f5857611f58611cff565b5060051b60200190565b600082601f830112611f7357600080fd5b81356020611f88611f8383611f3e565b611d7c565b82815260059290921b84018101918181019086841115611fa757600080fd5b8286015b84811015611fc957611fbc81611df4565b8352918301918301611fab565b509695505050505050565b600082601f830112611fe557600080fd5b81356020611ff5611f8383611f3e565b82815260059290921b8401810191818101908684111561201457600080fd5b8286015b84811015611fc95761202981611dcb565b8352918301918301612018565b6000806040838503121561204957600080fd5b823567ffffffffffffffff8082111561206157600080fd5b90840190610140828703121561207657600080fd5b61207e611d58565b823581526020830135602082015260408301358281111561209e57600080fd5b6120aa88828601611f62565b6040830152506120bc60608401611dcb565b60608201526120cd60808401611df4565b60808201526120de60a08401611df4565b60a08201526120ef60c08401611e06565b60c082015261210060e08401611dcb565b60e0820152610100808401358381111561211957600080fd5b61212589828701611fd4565b828401525050610120808401358381111561213f57600080fd5b61214b89828701611fd4565b82840152505080945050602085013591508082111561216957600080fd5b50611f3485828601611e1c565b60006020828403121561218857600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611def57600080fd5b6000806000606084860312156121c257600080fd5b6121cb8461218f565b92506121d96020850161218f565b9150604084015163ffffffff811681146121f257600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261226157600080fd5b83018035915067ffffffffffffffff82111561227c57600080fd5b60200191503681900382131561229157600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156115935761159361235a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b818103818111156115935761159361235a565b61ffff8281168282160390808211156123f9576123f961235a565b5092915050565b80820281158282048414176115935761159361235a565b60008261244d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561246457600080fd5b8151801515811461247457600080fd5b9392505050565b60005b8381101561249657818101518382015260200161247e565b50506000910152565b600082516124b181846020870161247b565b9190910192915050565b60208152600082518060208401526124da81604085016020870161247b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220200d00eba2c244bcc4394586e11bed52f1bde27d737f84e6823312ec945bdf2064736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611e34565b610066565b60405190815260200160405180910390f35b610041610061366004612036565b6109e7565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101949190612176565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb6121fd565b0497505061030189602001518a60a00151611569565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611599565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61222c565b6040518563ffffffff1660e01b81526004016104db9493929190612298565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b505050506101008a01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190612176565b90508481108061076b57506107688986612389565b81105b156107a2576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c48b60c001518c61010001518d6080015161ffff168e602001518d61162b565b985085156108f35787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108ad576040519150601f19603f3d011682016040523d82523d6000602084013e6108b2565b606091505b50509050806108ed576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610927565b6109278b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b85610937578a610100015161093a565b60005b73ffffffffffffffffffffffffffffffffffffffff168761095f578b60e00151610962565b60005b73ffffffffffffffffffffffffffffffffffffffff168c60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38e600001518d6040516109d1929190918252602082015260400190565b60405180910390a4505050505050505092915050565b60008260c0015165ffffffffffff16421115610a2f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1092916000918291908290610a7557610a7561239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610ac657610ac661239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610ba4578761010001518481518110610b0557610b0561239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9f9190612176565b610ba6565b475b90506000610bc889604001518a600001518b61010001518c61012001516116e4565b9050610bdc89602001518a60800151611569565b8160018351610beb91906123cb565b81518110610bfb57610bfb61239c565b60200260200101511015610c3b576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610d725788513414610c7b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b5050505050610d6d896101200151600081518110610d1b57610d1b61239c565b60200260200101518a600001518b6101000151600081518110610d4057610d4061239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b610fc7565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610de157610de161239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610e87919061222c565b6040518563ffffffff1660e01b8152600401610ea69493929190612298565b600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610f1557610f1561239c565b60200260200101518c600001518d6101000151600081518110610f3a57610f3a61239c565b60200260200101516040518563ffffffff1660e01b8152600401610f94949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610fae57600080fd5b505af1158015610fc2573d6000803e3d6000fd5b505050505b60005b858110156111d0576000610fdf826001612389565b905060008b61010001518281518110610ffa57610ffa61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c6101000151848151811061102f5761102f61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061105957600061105c565b60015b9050600060028d61010001515161107391906123cb565b841061107f573061109f565b8c610120015183815181106110965761109661239c565b60200260200101515b90508c610120015184815181106110b8576110b861239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836110ff578685815181106110f2576110f261239c565b6020026020010151611102565b60005b8461110e576000611129565b8786815181106111205761112061239c565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156111a957600080fd5b505af11580156111bd573d6000803e3d6000fd5b505060019095019450610fca9350505050565b50600089610100015186815181106111ea576111ea61239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190612176565b90508281108061129c57506112998884612389565b81105b156112d3576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113278a60e001518b610100015188815181106112f2576112f261239c565b60200260200101518c60a0015161ffff168d60200151868b8151811061131a5761131a61239c565b602002602001015161162b565b975083156114565786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611410576040519150601f19603f3d011682016040523d82523d6000602084013e611415565b606091505b5050905080611450576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611476565b6114768a60600151898c61010001518981518110610d4057610d4061239c565b8361149f5789610100015186815181106114925761149261239c565b60200260200101516114a2565b60005b73ffffffffffffffffffffffffffffffffffffffff16856114e2578a61010001516000815181106114d5576114d561239c565b60200260200101516114e5565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60e0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c604051611554929190918252602082015260400190565b60405180910390a45050505050505092915050565b600061271061157883826123de565b6115869061ffff1685612400565b6115909190612417565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611626908490611919565b505050565b60006107d0841115611672576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611684575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116ba57606460328402046116bd565b60005b90508083038382146116d5576116d58a8a8484611a28565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561170457611704611cff565b60405190808252806020026020018201604052801561172d578160200160208202803683370190505b50915084826000815181106117445761174461239c565b60200260200101818152505060005b8181101561190f57600085828151811061176f5761176f61239c565b602002602001015190506000868360016117899190612389565b815181106117995761179961239c565b6020026020010151905060008984815181106117b7576117b761239c565b60200260200101516127106117cc91906123de565b61ffff1690506000808886815181106117e7576117e761239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185d91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156118b857905b828b0282612710020181848d0202816118d3576118d36121fd565b049a508a886118e3886001612389565b815181106118f3576118f361239c565b6020908102919091010152505060019093019250611753915050565b5050949350505050565b600061197b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611af09092919063ffffffff16565b905080516000148061199c57508080602001905181019061199c9190612452565b611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611669565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611aff8484600085611b07565b949350505050565b606082471015611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611669565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bc2919061249f565b60006040518083038185875af1925050503d8060008114611bff576040519150601f19603f3d011682016040523d82523d6000602084013e611c04565b606091505b5091509150611c1587838387611c20565b979650505050505050565b60608315611cb6578251600003611caf5773ffffffffffffffffffffffffffffffffffffffff85163b611caf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611669565b5081611aff565b611aff8383815115611ccb5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166991906124bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611d5257611d52611cff565b60405290565b604051610140810167ffffffffffffffff81118282101715611d5257611d52611cff565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc357611dc3611cff565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611def57600080fd5b919050565b803561ffff81168114611def57600080fd5b803565ffffffffffff81168114611def57600080fd5b600060408284031215611e2e57600080fd5b50919050565b600080828403610180811215611e4957600080fd5b61016080821215611e5957600080fd5b611e61611d2e565b91508435825260208501356020830152611e7d60408601611dcb565b6040830152611e8e60608601611dcb565b6060830152611e9f60808601611df4565b6080830152611eb060a08601611df4565b60a0830152611ec160c08601611dcb565b60c0830152611ed260e08601611dcb565b60e0830152610100611ee5818701611dcb565b90830152610120611ef7868201611df4565b90830152610140611f09868201611e06565b9083015290925083013567ffffffffffffffff811115611f2857600080fd5b611f3485828601611e1c565b9150509250929050565b600067ffffffffffffffff821115611f5857611f58611cff565b5060051b60200190565b600082601f830112611f7357600080fd5b81356020611f88611f8383611f3e565b611d7c565b82815260059290921b84018101918181019086841115611fa757600080fd5b8286015b84811015611fc957611fbc81611df4565b8352918301918301611fab565b509695505050505050565b600082601f830112611fe557600080fd5b81356020611ff5611f8383611f3e565b82815260059290921b8401810191818101908684111561201457600080fd5b8286015b84811015611fc95761202981611dcb565b8352918301918301612018565b6000806040838503121561204957600080fd5b823567ffffffffffffffff8082111561206157600080fd5b90840190610140828703121561207657600080fd5b61207e611d58565b823581526020830135602082015260408301358281111561209e57600080fd5b6120aa88828601611f62565b6040830152506120bc60608401611dcb565b60608201526120cd60808401611df4565b60808201526120de60a08401611df4565b60a08201526120ef60c08401611e06565b60c082015261210060e08401611dcb565b60e0820152610100808401358381111561211957600080fd5b61212589828701611fd4565b828401525050610120808401358381111561213f57600080fd5b61214b89828701611fd4565b82840152505080945050602085013591508082111561216957600080fd5b50611f3485828601611e1c565b60006020828403121561218857600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611def57600080fd5b6000806000606084860312156121c257600080fd5b6121cb8461218f565b92506121d96020850161218f565b9150604084015163ffffffff811681146121f257600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261226157600080fd5b83018035915067ffffffffffffffff82111561227c57600080fd5b60200191503681900382131561229157600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156115935761159361235a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b818103818111156115935761159361235a565b61ffff8281168282160390808211156123f9576123f961235a565b5092915050565b80820281158282048414176115935761159361235a565b60008261244d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561246457600080fd5b8151801515811461247457600080fd5b9392505050565b60005b8381101561249657818101518382015260200161247e565b50506000910152565b600082516124b181846020870161247b565b9190910192915050565b60208152600082518060208401526124da81604085016020870161247b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220200d00eba2c244bcc4394586e11bed52f1bde27d737f84e6823312ec945bdf2064736f6c63430008130033", + "numDeployments": 12, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"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\":\"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\":\"uniswapV2LikeExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"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\":\"uniswapV2LikeExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\\n * NOTE: The tokens must already have been moved to the first pool\\n */\\n function uniswapV2LikeExactInputSingleInternal(\\n ExactInputSingleParams memory params\\n ) internal returns (uint256 amountOut) {\\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\\n } else {\\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\\n }\\n\\n return uniswapV2LikeExactInputSingleInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 the pool\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n params.pool,\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n\\n return uniswapV2LikeExactInputSingleInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputInternal(\\n ExactInputParams calldata params\\n ) internal returns (uint256 amountOut) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n address[] memory tokens = params.tokens;\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = tokens[0] == address(0);\\n bool isToEth = tokens[poolLength] == address(0);\\n\\n if (isFromEth) {\\n tokens[0] = address(s.weth);\\n }\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : tokens[0],\\n isToEth ? address(0) : tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokens[0] == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\\n }\\n\\n return uniswapV2LikeExactInputInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\n // Permit tokens / set allowance\\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n\\n return uniswapV2LikeExactInputInternal(params);\\n }\\n}\\n\",\"keccak256\":\"0x2264d60e017f7ec8aa13691a2cabd116d785824587c832a5cb8dbaa5336599c1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Like is ILibStarVault, ILibWarp {\\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 ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInputSinglePermit(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInputPermit(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x61257f389c4a69c463baafad1a008ed2e9d68936a7e4a2cbe5a0cdc60df61e40\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b5061299a806100206000396000f3fe60806040526004361061003f5760003560e01c806311f1fdef14610044578063baa8ed3514610076578063c83ee48414610089578063d1b72bc41461009c575b600080fd5b34801561005057600080fd5b5061006461005f366004612268565b6100bc565b60405190815260200160405180910390f35b6100646100843660046122b9565b610319565b6100646100973660046122e9565b61052d565b3480156100a857600080fd5b506100646100b736600461231e565b610766565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610126906101008c01908c016123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161015d6101608b016101408c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161018f61016089016101408a016123d2565b65ffffffffffff1690526101a660208701876123ed565b6040518563ffffffff1660e01b81526004016101c59493929190612459565b600060405180830381600087803b1580156101df57600080fd5b505af11580156101f3573d6000803e3d6000fd5b5050505061021e7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c785163361024e60808701606088016123a1565b8635610261610100890160e08a016123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102df57600080fd5b505af11580156102f3573d6000803e3d6000fd5b505050506103108380360381019061030b91906125ad565b610a0c565b90505b92915050565b600061032d610160830161014084016123d2565b65ffffffffffff1642111561036e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610381610100840160e085016123a1565b73ffffffffffffffffffffffffffffffffffffffff16036104d657348235146103d6576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561046257600080fd5b505af1158015610476573d6000803e3d6000fd5b50505050506104d182606001602081019061049191906123a1565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff169084356110ca565b61051b565b61051b336104ea60808501606086016123a1565b84356104fd610100870160e088016123a1565b73ffffffffffffffffffffffffffffffffffffffff169291906111a3565b61031361030b368490038401846125ad565b600061053f60e0830160c084016123d2565b65ffffffffffff16421115610580576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610590610100840184612679565b60008181106105a1576105a16126e1565b90506020020160208101906105b691906123a1565b73ffffffffffffffffffffffffffffffffffffffff16036106ef573482351461060b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561069757600080fd5b505af11580156106ab573d6000803e3d6000fd5b50505050506106ea828061012001906106c49190612679565b60008181106106d5576106d56126e1565b905060200201602081019061049191906123a1565b61075d565b61075d33610701610120850185612679565b6000818110610712576107126126e1565b905060200201602081019061072791906123a1565b8435610737610100870187612679565b6000818110610748576107486126e1565b90506020020160208101906104fd91906123a1565b61031382611207565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915260009173ffffffffffffffffffffffffffffffffffffffff1690632b67b5709033908060608101806107c96101008b018b612679565b60008181106107da576107da6126e1565b90506020020160208101906107ef91906123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161082460e08b0160c08c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161085460e0890160c08a016123d2565b65ffffffffffff16905261086b60208701876123ed565b6040518563ffffffff1660e01b815260040161088a9493929190612459565b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506108e37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633610911610120870187612679565b6000818110610922576109226126e1565b905060200201602081019061093791906123a1565b8635610947610100890189612679565b6000818110610958576109586126e1565b905060200201602081019061096d91906123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050505061031083611207565b60e08101516101008201516000917f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff918216159116158381610af8576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af39190612710565b610afa565b475b90508215610b2057835473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8115610b4557835473ffffffffffffffffffffffffffffffffffffffff166101008701525b600080876060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915087610100015173ffffffffffffffffffffffffffffffffffffffff168860e0015173ffffffffffffffffffffffffffffffffffffffff161115610c1f57905b610120880151885161ffff6127109283031691840290820290810190830281610c4a57610c4a612797565b04975050610c6088602001518960a00151611b42565b871015610c99576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1610610cde576000610ce1565b60015b9050886060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610d0e5789610d11565b60005b83610d1d576000610d1f565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015610d8957600080fd5b505af1158015610d9d573d6000803e3d6000fd5b505050506101008901516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190612710565b905084811080610e4f5750610e4c89866127f5565b81105b15610e86576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea88a60c001518b61010001518c6080015161ffff168d602001518d611b69565b98508515610fd75787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d8060008114610f91576040519150601f19603f3d011682016040523d82523d6000602084013e610f96565b606091505b5050905080610fd1576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061100b565b61100b8a604001518a8c610100015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b8561101b5789610100015161101e565b60005b73ffffffffffffffffffffffffffffffffffffffff1687611043578a60e00151611046565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518d6040516110b5929190918252602082015260400190565b60405180910390a45050505050505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261119e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c22565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161111c565b50505050565b60007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1081611239610100850185612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061127b92505050610120860186612679565b9050905060008073ffffffffffffffffffffffffffffffffffffffff16836000815181106112ab576112ab6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168484815181106112f7576112f76126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115611387578454845173ffffffffffffffffffffffffffffffffffffffff90911690859060009061134c5761134c6126e1565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008161143f578484815181106113a0576113a06126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143a9190612710565b611441565b475b905060006114d061145560408b018b612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508c3591508990506114996101208e018e612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d3192505050565b90506114ef60208a01356114ea60a08c0160808d01612808565b611b42565b81600183516114fe9190612823565b8151811061150e5761150e6126e1565b6020026020010151101561154e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8581101561176f5760006115668260016127f5565b9050600088828151811061157c5761157c6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168984815181106115ac576115ac6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106115d65760006115d9565b60015b9050600060028a516115eb9190612823565b84106115f7573061162a565b6116056101208e018e612679565b84818110611615576116156126e1565b905060200201602081019061162a91906123a1565b905061163a6101208e018e612679565b8581811061164a5761164a6126e1565b905060200201602081019061165f91906123a1565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361169e57868581518110611691576116916126e1565b60200260200101516116a1565b60005b846116ad5760006116c8565b8786815181106116bf576116bf6126e1565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561174857600080fd5b505af115801561175c573d6000803e3d6000fd5b5050600190950194506115519350505050565b506000868681518110611784576117846126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190612710565b905082811080611836575061183389846127f5565b81105b1561186d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d66118816101008c0160e08d016123a1565b888881518110611893576118936126e1565b60200260200101518c60a00160208101906118ae9190612808565b61ffff168d60200135868b815181106118c9576118c96126e1565b6020026020010151611b69565b98508315611a125787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561194957600080fd5b505af115801561195d573d6000803e3d6000fd5b506000925061197591505060808c0160608d016123a1565b73ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146119cc576040519150601f19603f3d011682016040523d82523d6000602084013e6119d1565b606091505b5050905080611a0c576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611a65565b611a65611a2560808c0160608d016123a1565b8a898981518110611a3857611a386126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b83611a8957868681518110611a7c57611a7c6126e1565b6020026020010151611a8c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685611ac75787600081518110611aba57611aba6126e1565b6020026020010151611aca565b60005b73ffffffffffffffffffffffffffffffffffffffff16611af16101008d0160e08e016123a1565b604080518e358152602081018e905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f391016110b5565b6000612710611b518382612836565b611b5f9061ffff1685612858565b610310919061286f565b60006107d0841115611bb0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611bc2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611bf85760646032840204611bfb565b60005b9050808303838214611c1357611c138a8a8484611f66565b50505090910395945050505050565b6000611c84826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661202e9092919063ffffffff16565b9050805160001480611ca5575080806020019051810190611ca591906128aa565b61119e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611ba7565b805182516060919067ffffffffffffffff811115611d5157611d5161251b565b604051908082528060200260200182016040528015611d7a578160200160208202803683370190505b5091508482600081518110611d9157611d916126e1565b60200260200101818152505060005b81811015611f5c576000858281518110611dbc57611dbc6126e1565b60200260200101519050600086836001611dd691906127f5565b81518110611de657611de66126e1565b602002602001015190506000898481518110611e0457611e046126e1565b6020026020010151612710611e199190612836565b61ffff169050600080888681518110611e3457611e346126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115611f0557905b828b0282612710020181848d020281611f2057611f20612797565b049a508a88611f308860016127f5565b81518110611f4057611f406126e1565b6020908102919091010152505060019093019250611da0915050565b5050949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061203d8484600085612045565b949350505050565b6060824710156120d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611ba7565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161210091906128f7565b60006040518083038185875af1925050503d806000811461213d576040519150601f19603f3d011682016040523d82523d6000602084013e612142565b606091505b50915091506121538783838761215e565b979650505050505050565b606083156121f45782516000036121ed5773ffffffffffffffffffffffffffffffffffffffff85163b6121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611ba7565b508161203d565b61203d83838151156122095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79190612913565b6000610160828403121561225057600080fd5b50919050565b60006040828403121561225057600080fd5b600080610180838503121561227c57600080fd5b612286848461223d565b915061016083013567ffffffffffffffff8111156122a357600080fd5b6122af85828601612256565b9150509250929050565b600061016082840312156122cc57600080fd5b610310838361223d565b6000610140828403121561225057600080fd5b6000602082840312156122fb57600080fd5b813567ffffffffffffffff81111561231257600080fd5b61203d848285016122d6565b6000806040838503121561233157600080fd5b823567ffffffffffffffff8082111561234957600080fd5b612355868387016122d6565b9350602085013591508082111561236b57600080fd5b506122af85828601612256565b803573ffffffffffffffffffffffffffffffffffffffff8116811461239c57600080fd5b919050565b6000602082840312156123b357600080fd5b61031082612378565b803565ffffffffffff8116811461239c57600080fd5b6000602082840312156123e457600080fd5b610310826123bc565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261242257600080fd5b83018035915067ffffffffffffffff82111561243d57600080fd5b60200191503681900382131561245257600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715612595577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803561ffff8116811461239c57600080fd5b600061016082840312156125c057600080fd5b6125c861254a565b82358152602083013560208201526125e260408401612378565b60408201526125f360608401612378565b60608201526126046080840161259b565b608082015261261560a0840161259b565b60a082015261262660c08401612378565b60c082015261263760e08401612378565b60e082015261010061264a818501612378565b9082015261012061265c84820161259b565b9082015261014061266e8482016123bc565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126ae57600080fd5b83018035915067ffffffffffffffff8211156126c957600080fd5b6020019150600581901b360382131561245257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561272257600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461239c57600080fd5b60008060006060848603121561275c57600080fd5b61276584612729565b925061277360208501612729565b9150604084015163ffffffff8116811461278c57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610313576103136127c6565b60006020828403121561281a57600080fd5b6103108261259b565b81810381811115610313576103136127c6565b61ffff828116828216039080821115612851576128516127c6565b5092915050565b8082028115828204841417610313576103136127c6565b6000826128a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156128bc57600080fd5b815180151581146128cc57600080fd5b9392505050565b60005b838110156128ee5781810151838201526020016128d6565b50506000910152565b600082516129098184602087016128d3565b9190910192915050565b60208152600082518060208401526129328160408501602087016128d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de44c59485b64a44309171bd5ec5a3aa82d4e9417058be7ee66435ce87ad82ed64736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003f5760003560e01c806311f1fdef14610044578063baa8ed3514610076578063c83ee48414610089578063d1b72bc41461009c575b600080fd5b34801561005057600080fd5b5061006461005f366004612268565b6100bc565b60405190815260200160405180910390f35b6100646100843660046122b9565b610319565b6100646100973660046122e9565b61052d565b3480156100a857600080fd5b506100646100b736600461231e565b610766565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610126906101008c01908c016123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161015d6101608b016101408c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161018f61016089016101408a016123d2565b65ffffffffffff1690526101a660208701876123ed565b6040518563ffffffff1660e01b81526004016101c59493929190612459565b600060405180830381600087803b1580156101df57600080fd5b505af11580156101f3573d6000803e3d6000fd5b5050505061021e7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c785163361024e60808701606088016123a1565b8635610261610100890160e08a016123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102df57600080fd5b505af11580156102f3573d6000803e3d6000fd5b505050506103108380360381019061030b91906125ad565b610a0c565b90505b92915050565b600061032d610160830161014084016123d2565b65ffffffffffff1642111561036e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610381610100840160e085016123a1565b73ffffffffffffffffffffffffffffffffffffffff16036104d657348235146103d6576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561046257600080fd5b505af1158015610476573d6000803e3d6000fd5b50505050506104d182606001602081019061049191906123a1565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff169084356110ca565b61051b565b61051b336104ea60808501606086016123a1565b84356104fd610100870160e088016123a1565b73ffffffffffffffffffffffffffffffffffffffff169291906111a3565b61031361030b368490038401846125ad565b600061053f60e0830160c084016123d2565b65ffffffffffff16421115610580576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610590610100840184612679565b60008181106105a1576105a16126e1565b90506020020160208101906105b691906123a1565b73ffffffffffffffffffffffffffffffffffffffff16036106ef573482351461060b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561069757600080fd5b505af11580156106ab573d6000803e3d6000fd5b50505050506106ea828061012001906106c49190612679565b60008181106106d5576106d56126e1565b905060200201602081019061049191906123a1565b61075d565b61075d33610701610120850185612679565b6000818110610712576107126126e1565b905060200201602081019061072791906123a1565b8435610737610100870187612679565b6000818110610748576107486126e1565b90506020020160208101906104fd91906123a1565b61031382611207565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915260009173ffffffffffffffffffffffffffffffffffffffff1690632b67b5709033908060608101806107c96101008b018b612679565b60008181106107da576107da6126e1565b90506020020160208101906107ef91906123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161082460e08b0160c08c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161085460e0890160c08a016123d2565b65ffffffffffff16905261086b60208701876123ed565b6040518563ffffffff1660e01b815260040161088a9493929190612459565b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506108e37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633610911610120870187612679565b6000818110610922576109226126e1565b905060200201602081019061093791906123a1565b8635610947610100890189612679565b6000818110610958576109586126e1565b905060200201602081019061096d91906123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050505061031083611207565b60e08101516101008201516000917f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff918216159116158381610af8576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af39190612710565b610afa565b475b90508215610b2057835473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8115610b4557835473ffffffffffffffffffffffffffffffffffffffff166101008701525b600080876060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915087610100015173ffffffffffffffffffffffffffffffffffffffff168860e0015173ffffffffffffffffffffffffffffffffffffffff161115610c1f57905b610120880151885161ffff6127109283031691840290820290810190830281610c4a57610c4a612797565b04975050610c6088602001518960a00151611b42565b871015610c99576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1610610cde576000610ce1565b60015b9050886060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610d0e5789610d11565b60005b83610d1d576000610d1f565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015610d8957600080fd5b505af1158015610d9d573d6000803e3d6000fd5b505050506101008901516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190612710565b905084811080610e4f5750610e4c89866127f5565b81105b15610e86576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea88a60c001518b61010001518c6080015161ffff168d602001518d611b69565b98508515610fd75787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d8060008114610f91576040519150601f19603f3d011682016040523d82523d6000602084013e610f96565b606091505b5050905080610fd1576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061100b565b61100b8a604001518a8c610100015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b8561101b5789610100015161101e565b60005b73ffffffffffffffffffffffffffffffffffffffff1687611043578a60e00151611046565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518d6040516110b5929190918252602082015260400190565b60405180910390a45050505050505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261119e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c22565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161111c565b50505050565b60007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1081611239610100850185612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061127b92505050610120860186612679565b9050905060008073ffffffffffffffffffffffffffffffffffffffff16836000815181106112ab576112ab6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168484815181106112f7576112f76126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115611387578454845173ffffffffffffffffffffffffffffffffffffffff90911690859060009061134c5761134c6126e1565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008161143f578484815181106113a0576113a06126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143a9190612710565b611441565b475b905060006114d061145560408b018b612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508c3591508990506114996101208e018e612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d3192505050565b90506114ef60208a01356114ea60a08c0160808d01612808565b611b42565b81600183516114fe9190612823565b8151811061150e5761150e6126e1565b6020026020010151101561154e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8581101561176f5760006115668260016127f5565b9050600088828151811061157c5761157c6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168984815181106115ac576115ac6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106115d65760006115d9565b60015b9050600060028a516115eb9190612823565b84106115f7573061162a565b6116056101208e018e612679565b84818110611615576116156126e1565b905060200201602081019061162a91906123a1565b905061163a6101208e018e612679565b8581811061164a5761164a6126e1565b905060200201602081019061165f91906123a1565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361169e57868581518110611691576116916126e1565b60200260200101516116a1565b60005b846116ad5760006116c8565b8786815181106116bf576116bf6126e1565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561174857600080fd5b505af115801561175c573d6000803e3d6000fd5b5050600190950194506115519350505050565b506000868681518110611784576117846126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190612710565b905082811080611836575061183389846127f5565b81105b1561186d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d66118816101008c0160e08d016123a1565b888881518110611893576118936126e1565b60200260200101518c60a00160208101906118ae9190612808565b61ffff168d60200135868b815181106118c9576118c96126e1565b6020026020010151611b69565b98508315611a125787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561194957600080fd5b505af115801561195d573d6000803e3d6000fd5b506000925061197591505060808c0160608d016123a1565b73ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146119cc576040519150601f19603f3d011682016040523d82523d6000602084013e6119d1565b606091505b5050905080611a0c576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611a65565b611a65611a2560808c0160608d016123a1565b8a898981518110611a3857611a386126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b83611a8957868681518110611a7c57611a7c6126e1565b6020026020010151611a8c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685611ac75787600081518110611aba57611aba6126e1565b6020026020010151611aca565b60005b73ffffffffffffffffffffffffffffffffffffffff16611af16101008d0160e08e016123a1565b604080518e358152602081018e905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f391016110b5565b6000612710611b518382612836565b611b5f9061ffff1685612858565b610310919061286f565b60006107d0841115611bb0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611bc2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611bf85760646032840204611bfb565b60005b9050808303838214611c1357611c138a8a8484611f66565b50505090910395945050505050565b6000611c84826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661202e9092919063ffffffff16565b9050805160001480611ca5575080806020019051810190611ca591906128aa565b61119e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611ba7565b805182516060919067ffffffffffffffff811115611d5157611d5161251b565b604051908082528060200260200182016040528015611d7a578160200160208202803683370190505b5091508482600081518110611d9157611d916126e1565b60200260200101818152505060005b81811015611f5c576000858281518110611dbc57611dbc6126e1565b60200260200101519050600086836001611dd691906127f5565b81518110611de657611de66126e1565b602002602001015190506000898481518110611e0457611e046126e1565b6020026020010151612710611e199190612836565b61ffff169050600080888681518110611e3457611e346126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115611f0557905b828b0282612710020181848d020281611f2057611f20612797565b049a508a88611f308860016127f5565b81518110611f4057611f406126e1565b6020908102919091010152505060019093019250611da0915050565b5050949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061203d8484600085612045565b949350505050565b6060824710156120d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611ba7565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161210091906128f7565b60006040518083038185875af1925050503d806000811461213d576040519150601f19603f3d011682016040523d82523d6000602084013e612142565b606091505b50915091506121538783838761215e565b979650505050505050565b606083156121f45782516000036121ed5773ffffffffffffffffffffffffffffffffffffffff85163b6121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611ba7565b508161203d565b61203d83838151156122095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79190612913565b6000610160828403121561225057600080fd5b50919050565b60006040828403121561225057600080fd5b600080610180838503121561227c57600080fd5b612286848461223d565b915061016083013567ffffffffffffffff8111156122a357600080fd5b6122af85828601612256565b9150509250929050565b600061016082840312156122cc57600080fd5b610310838361223d565b6000610140828403121561225057600080fd5b6000602082840312156122fb57600080fd5b813567ffffffffffffffff81111561231257600080fd5b61203d848285016122d6565b6000806040838503121561233157600080fd5b823567ffffffffffffffff8082111561234957600080fd5b612355868387016122d6565b9350602085013591508082111561236b57600080fd5b506122af85828601612256565b803573ffffffffffffffffffffffffffffffffffffffff8116811461239c57600080fd5b919050565b6000602082840312156123b357600080fd5b61031082612378565b803565ffffffffffff8116811461239c57600080fd5b6000602082840312156123e457600080fd5b610310826123bc565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261242257600080fd5b83018035915067ffffffffffffffff82111561243d57600080fd5b60200191503681900382131561245257600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715612595577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803561ffff8116811461239c57600080fd5b600061016082840312156125c057600080fd5b6125c861254a565b82358152602083013560208201526125e260408401612378565b60408201526125f360608401612378565b60608201526126046080840161259b565b608082015261261560a0840161259b565b60a082015261262660c08401612378565b60c082015261263760e08401612378565b60e082015261010061264a818501612378565b9082015261012061265c84820161259b565b9082015261014061266e8482016123bc565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126ae57600080fd5b83018035915067ffffffffffffffff8211156126c957600080fd5b6020019150600581901b360382131561245257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561272257600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461239c57600080fd5b60008060006060848603121561275c57600080fd5b61276584612729565b925061277360208501612729565b9150604084015163ffffffff8116811461278c57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610313576103136127c6565b60006020828403121561281a57600080fd5b6103108261259b565b81810381811115610313576103136127c6565b61ffff828116828216039080821115612851576128516127c6565b5092915050565b8082028115828204841417610313576103136127c6565b6000826128a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156128bc57600080fd5b815180151581146128cc57600080fd5b9392505050565b60005b838110156128ee5781810151838201526020016128d6565b50506000910152565b600082516129098184602087016128d3565b9190910192915050565b60208152600082518060208401526129328160408501602087016128d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de44c59485b64a44309171bd5ec5a3aa82d4e9417058be7ee66435ce87ad82ed64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/UniV2RouterFacet.json b/packages/hardhat/deployments/mainnet/UniV2RouterFacet.json index b56c67dd..27aee578 100644 --- a/packages/hardhat/deployments/mainnet/UniV2RouterFacet.json +++ b/packages/hardhat/deployments/mainnet/UniV2RouterFacet.json @@ -1,5 +1,5 @@ { - "address": "0x9Ad04EE66B8F9386eFBb0bdBc998a2fEF00D6A45", + "address": "0x854b5c3d9225f34F719A3CD06be4Da182a5104A0", "abi": [ { "inputs": [], @@ -116,6 +116,67 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV2ExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -183,7 +244,73 @@ "type": "tuple" } ], - "name": "uniswapV2ExactInput", + "name": "uniswapV2ExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV2ExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -266,7 +393,7 @@ "type": "tuple" } ], - "name": "uniswapV2ExactInputSingle", + "name": "uniswapV2ExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -274,32 +401,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0xc5a5bf1f8a7a93ecc8815f6c9933fba90f3b084f1e0312d1d4b42db129199638", + "transactionHash": "0x42911bb23098768880da151af319aca7e71c3e4b87bac01c68afb5e90bee473d", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x9Ad04EE66B8F9386eFBb0bdBc998a2fEF00D6A45", - "transactionIndex": 65, - "gasUsed": "2051634", + "contractAddress": "0x854b5c3d9225f34F719A3CD06be4Da182a5104A0", + "transactionIndex": 60, + "gasUsed": "2386718", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x7d8dd480aac87e026520d860e841ec49f81a961063e8c2bae19be6686326a0b3", - "transactionHash": "0xc5a5bf1f8a7a93ecc8815f6c9933fba90f3b084f1e0312d1d4b42db129199638", + "blockHash": "0x65856fedbbfd6526be040eea386571549421c96e144e37f0ed92cef845ad33b1", + "transactionHash": "0x42911bb23098768880da151af319aca7e71c3e4b87bac01c68afb5e90bee473d", "logs": [], - "blockNumber": 18383668, - "cumulativeGasUsed": "9363346", + "blockNumber": 18511218, + "cumulativeGasUsed": "7943276", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 16, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmountOut\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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\\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 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 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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert 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 EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 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 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.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 = LibStarVault.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 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 EthTransferFailed();\\n }\\n } else {\\n IERC20(params.path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.path[0],\\n isToEth ? address(0) : params.path[pathLengthMinusOne],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x9a9431661e2698a7183fd4938ec2ff736abbc7534263a2fb10b7b6e5d09945a5\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Router.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Router is ILibStarVault, ILibWarp {\\n error EthTransferFailed();\\n error ZeroAmountOut();\\n error IncorrectEthValue();\\n error InsufficientOutputAmount();\\n error DeadlineExpired();\\n\\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\":\"0x8d38e44f2c5edb420d16ed3fe9cd82ef7aca30e52d330e5e4b3cdce449b28149\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612451806100206000396000f3fe6080604052600436106100295760003560e01c80630d164c381461002e578063a817b67d14610053575b600080fd5b61004161003c366004611ec6565b610066565b60405190815260200160405180910390f35b610041610061366004611fc2565b610b74565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e0830151517fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c906000906100e5906001906120cd565b905060008073ffffffffffffffffffffffffffffffffffffffff168660e00151600081518110610117576101176120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168760e001518481518110610167576101676120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115610205578360000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168760e001516000815181106101ca576101ca6120e0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b8015610281578360000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168760e001518481518110610246576102466120e0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b6002840154875160e089015160009283926102b49273ffffffffffffffffffffffffffffffffffffffff909216916113cc565b915091506102ca89602001518a60600151611671565b81600183516102d991906120cd565b815181106102e9576102e96120e0565b60200260200101511015610329576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b831561045a5788513414610369576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103d557600080fd5b505af11580156103e9573d6000803e3d6000fd5b505050505061045582600081518110610404576104046120e0565b60200260200101518a600001518b60e00151600081518110610428576104286120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116a19092919063ffffffff16565b6106a9565b8560030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f60e001516000815181106104c8576104c86120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60a0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff168152508b806020019061056e919061210f565b6040518563ffffffff1660e01b815260040161058d949392919061217b565b600060405180830381600087803b1580156105a757600080fd5b505af11580156105bb573d6000803e3d6000fd5b5050506003870154835173ffffffffffffffffffffffffffffffffffffffff90911691506336c7851690339085906000906105f8576105f86120e0565b60200260200101518c600001518d60e0015160008151811061061c5761061c6120e0565b60200260200101516040518563ffffffff1660e01b8152600401610676949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b15801561069057600080fd5b505af11580156106a4573d6000803e3d6000fd5b505050505b60005b858110156108a45760006106c182600161223d565b905060008b60e0015182815181106106db576106db6120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c60e00151848151811061070f5761070f6120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061073957600061073c565b60015b9050600060028d60e001515161075291906120cd565b841061075e5730610779565b858381518110610770576107706120e0565b60200260200101515b905085848151811061078d5761078d6120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836107d4578685815181106107c7576107c76120e0565b60200260200101516107d7565b60005b846107e35760006107fe565b8786815181106107f5576107f56120e0565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561087e57600080fd5b505af1158015610892573d6000803e3d6000fd5b505050508360010193505050506106ac565b506108f88960c001518a60e0015187815181106108c3576108c36120e0565b60200260200101518b6080015161ffff168c60200151858a815181106108eb576108eb6120e0565b6020026020010151611733565b965086600003610934576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215610a655785546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156109a957600080fd5b505af11580156109bd573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114610a1f576040519150601f19603f3d011682016040523d82523d6000602084013e610a24565b606091505b5050905080610a5f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610a84565b610a848960400151888b60e001518881518110610428576104286120e0565b82610aac578860e001518581518110610a9f57610a9f6120e0565b6020026020010151610aaf565b60005b73ffffffffffffffffffffffffffffffffffffffff1684610aee578960e00151600081518110610ae157610ae16120e0565b6020026020010151610af1565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b604051610b60929190918252602082015260400190565b60405180910390a450505050505092915050565b60008260a0015165ffffffffffff16421115610bbc576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c9173ffffffffffffffffffffffffffffffffffffffff908116159116158115610c2e578254610100900473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8015610c5857825473ffffffffffffffffffffffffffffffffffffffff6101009182900416908701525b600283015460e0870151610100880151600092610c8d9273ffffffffffffffffffffffffffffffffffffffff909116916117ec565b90506000808273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d01919061226e565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff161115610d6557905b88516103e58082026103e88502019183020281610d8457610d846122be565b049650610d9989602001518a60600151611671565b871015610dd2576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610ec55788513414610e12576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610e7e57600080fd5b505af1158015610e92573d6000803e3d6000fd5b50508b5160e08d0151610ec0945073ffffffffffffffffffffffffffffffffffffffff1692508691506116a1565b611046565b60038601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d518216608084015260a0808f01805165ffffffffffff908116928601929092528e35821660c0860152918452306020808601919091529151169383019390935290921691632b67b57091339190610f51908d018d61210f565b6040518563ffffffff1660e01b8152600401610f70949392919061217b565b600060405180830381600087803b158015610f8a57600080fd5b505af1158015610f9e573d6000803e3d6000fd5b505050506003860154895160e08b01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8781166024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561102d57600080fd5b505af1158015611041573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff161061108b57600061108e565b60015b90508373ffffffffffffffffffffffffffffffffffffffff1663022c0d9f826110b757896110ba565b60005b836110c65760006110c8565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561113257600080fd5b505af1158015611146573d6000803e3d6000fd5b5050505061116c8a60c001518b61010001518c6080015161ffff168d602001518c611733565b9750876000036111a8576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84156112d95786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561121d57600080fd5b505af1158015611231573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611293576040519150601f19603f3d011682016040523d82523d6000602084013e611298565b606091505b50509050806112d3576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061130d565b61130d8a60400151898c610100015173ffffffffffffffffffffffffffffffffffffffff166116a19092919063ffffffff16565b8461131d57896101000151611320565b60005b73ffffffffffffffffffffffffffffffffffffffff1686611345578a60e00151611348565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c6040516113b7929190918252602082015260400190565b60405180910390a45050505050505092915050565b6060806000600184516113df91906120cd565b90508067ffffffffffffffff8111156113fa576113fa611d2b565b604051908082528060200260200182016040528015611423578160200160208202803683370190505b509250835167ffffffffffffffff81111561144057611440611d2b565b604051908082528060200260200182016040528015611469578160200160208202803683370190505b5091508482600081518110611480576114806120e0565b60200260200101818152505060005b818110156116675760008582815181106114ab576114ab6120e0565b602002602001015190506000868360016114c5919061223d565b815181106114d5576114d56120e0565b602002602001015190506114ea8983836117ec565b8684815181106114fc576114fc6120e0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506000806115448b85856117ec565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561158e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b2919061226e565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16111561160d57905b896103e502826103e80201818b6103e502028161162c5761162c6122be565b049950898761163c87600161223d565b8151811061164c5761164c6120e0565b602090810291909101015250506001909201915061148f9050565b5050935093915050565b600061271061168083826122ed565b61168e9061ffff168561230f565b6116989190612326565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261172e908490611945565b505050565b60006107d084111561177a576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561178c575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156117c257606460328402046117c5565b60005b90508083038382146117dd576117dd8a8a8484611a54565b50505090910395945050505050565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115611826579091905b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085811b8216602084015284901b1660348201528490604801604051602081830303815290604052805190602001206040516020016119079291907fff00000000000000000000000000000000000000000000000000000000000000815260609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016600183015260158201527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120949350505050565b60006119a7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611b1c9092919063ffffffff16565b90508051600014806119c85750808060200190518101906119c89190612361565b61172e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611771565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611b2b8484600085611b33565b949350505050565b606082471015611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611771565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bee91906123ae565b60006040518083038185875af1925050503d8060008114611c2b576040519150601f19603f3d011682016040523d82523d6000602084013e611c30565b606091505b5091509150611c4187838387611c4c565b979650505050505050565b60608315611ce2578251600003611cdb5773ffffffffffffffffffffffffffffffffffffffff85163b611cdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611771565b5081611b2b565b611b2b8383815115611cf75781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177191906123ca565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715611d7e57611d7e611d2b565b60405290565b604051610120810167ffffffffffffffff81118282101715611d7e57611d7e611d2b565b803573ffffffffffffffffffffffffffffffffffffffff81168114611dcc57600080fd5b919050565b803561ffff81168114611dcc57600080fd5b803565ffffffffffff81168114611dcc57600080fd5b600082601f830112611e0a57600080fd5b8135602067ffffffffffffffff80831115611e2757611e27611d2b565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6a57611e6a611d2b565b604052938452858101830193838101925087851115611e8857600080fd5b83870191505b84821015611c4157611e9f82611da8565b83529183019190830190611e8e565b600060408284031215611ec057600080fd5b50919050565b60008060408385031215611ed957600080fd5b823567ffffffffffffffff80821115611ef157600080fd5b908401906101008287031215611f0657600080fd5b611f0e611d5a565b8235815260208301356020820152611f2860408401611da8565b6040820152611f3960608401611dd1565b6060820152611f4a60808401611dd1565b6080820152611f5b60a08401611de3565b60a0820152611f6c60c08401611da8565b60c082015260e083013582811115611f8357600080fd5b611f8f88828601611df9565b60e08301525093506020850135915080821115611fab57600080fd5b50611fb885828601611eae565b9150509250929050565b600080828403610140811215611fd757600080fd5b61012080821215611fe757600080fd5b611fef611d84565b9150843582526020850135602083015261200b60408601611da8565b604083015261201c60608601611dd1565b606083015261202d60808601611dd1565b608083015261203e60a08601611de3565b60a083015261204f60c08601611da8565b60c083015261206060e08601611da8565b60e0830152610100612073818701611da8565b9083015290925083013567ffffffffffffffff81111561209257600080fd5b611fb885828601611eae565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561169b5761169b61209e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261214457600080fd5b83018035915067ffffffffffffffff82111561215f57600080fd5b60200191503681900382131561217457600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b8082018082111561169b5761169b61209e565b80516dffffffffffffffffffffffffffff81168114611dcc57600080fd5b60008060006060848603121561228357600080fd5b61228c84612250565b925061229a60208501612250565b9150604084015163ffffffff811681146122b357600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b61ffff8281168282160390808211156123085761230861209e565b5092915050565b808202811582820484141761169b5761169b61209e565b60008261235c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561237357600080fd5b8151801515811461238357600080fd5b9392505050565b60005b838110156123a557818101518382015260200161238d565b50506000910152565b600082516123c081846020870161238a565b9190910192915050565b60208152600082518060208401526123e981604085016020870161238a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212205c2186193f26754a210d4ead3a4fd7d498dab0a801ab37d6db00bca51b76c6a364736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80630d164c381461002e578063a817b67d14610053575b600080fd5b61004161003c366004611ec6565b610066565b60405190815260200160405180910390f35b610041610061366004611fc2565b610b74565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e0830151517fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c906000906100e5906001906120cd565b905060008073ffffffffffffffffffffffffffffffffffffffff168660e00151600081518110610117576101176120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168760e001518481518110610167576101676120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115610205578360000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168760e001516000815181106101ca576101ca6120e0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b8015610281578360000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168760e001518481518110610246576102466120e0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b6002840154875160e089015160009283926102b49273ffffffffffffffffffffffffffffffffffffffff909216916113cc565b915091506102ca89602001518a60600151611671565b81600183516102d991906120cd565b815181106102e9576102e96120e0565b60200260200101511015610329576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b831561045a5788513414610369576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103d557600080fd5b505af11580156103e9573d6000803e3d6000fd5b505050505061045582600081518110610404576104046120e0565b60200260200101518a600001518b60e00151600081518110610428576104286120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116a19092919063ffffffff16565b6106a9565b8560030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f60e001516000815181106104c8576104c86120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60a0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff168152508b806020019061056e919061210f565b6040518563ffffffff1660e01b815260040161058d949392919061217b565b600060405180830381600087803b1580156105a757600080fd5b505af11580156105bb573d6000803e3d6000fd5b5050506003870154835173ffffffffffffffffffffffffffffffffffffffff90911691506336c7851690339085906000906105f8576105f86120e0565b60200260200101518c600001518d60e0015160008151811061061c5761061c6120e0565b60200260200101516040518563ffffffff1660e01b8152600401610676949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b15801561069057600080fd5b505af11580156106a4573d6000803e3d6000fd5b505050505b60005b858110156108a45760006106c182600161223d565b905060008b60e0015182815181106106db576106db6120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c60e00151848151811061070f5761070f6120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061073957600061073c565b60015b9050600060028d60e001515161075291906120cd565b841061075e5730610779565b858381518110610770576107706120e0565b60200260200101515b905085848151811061078d5761078d6120e0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836107d4578685815181106107c7576107c76120e0565b60200260200101516107d7565b60005b846107e35760006107fe565b8786815181106107f5576107f56120e0565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561087e57600080fd5b505af1158015610892573d6000803e3d6000fd5b505050508360010193505050506106ac565b506108f88960c001518a60e0015187815181106108c3576108c36120e0565b60200260200101518b6080015161ffff168c60200151858a815181106108eb576108eb6120e0565b6020026020010151611733565b965086600003610934576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215610a655785546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156109a957600080fd5b505af11580156109bd573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114610a1f576040519150601f19603f3d011682016040523d82523d6000602084013e610a24565b606091505b5050905080610a5f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610a84565b610a848960400151888b60e001518881518110610428576104286120e0565b82610aac578860e001518581518110610a9f57610a9f6120e0565b6020026020010151610aaf565b60005b73ffffffffffffffffffffffffffffffffffffffff1684610aee578960e00151600081518110610ae157610ae16120e0565b6020026020010151610af1565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b604051610b60929190918252602082015260400190565b60405180910390a450505050505092915050565b60008260a0015165ffffffffffff16421115610bbc576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c9173ffffffffffffffffffffffffffffffffffffffff908116159116158115610c2e578254610100900473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8015610c5857825473ffffffffffffffffffffffffffffffffffffffff6101009182900416908701525b600283015460e0870151610100880151600092610c8d9273ffffffffffffffffffffffffffffffffffffffff909116916117ec565b90506000808273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d01919061226e565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff161115610d6557905b88516103e58082026103e88502019183020281610d8457610d846122be565b049650610d9989602001518a60600151611671565b871015610dd2576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610ec55788513414610e12576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610e7e57600080fd5b505af1158015610e92573d6000803e3d6000fd5b50508b5160e08d0151610ec0945073ffffffffffffffffffffffffffffffffffffffff1692508691506116a1565b611046565b60038601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d518216608084015260a0808f01805165ffffffffffff908116928601929092528e35821660c0860152918452306020808601919091529151169383019390935290921691632b67b57091339190610f51908d018d61210f565b6040518563ffffffff1660e01b8152600401610f70949392919061217b565b600060405180830381600087803b158015610f8a57600080fd5b505af1158015610f9e573d6000803e3d6000fd5b505050506003860154895160e08b01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8781166024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561102d57600080fd5b505af1158015611041573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff161061108b57600061108e565b60015b90508373ffffffffffffffffffffffffffffffffffffffff1663022c0d9f826110b757896110ba565b60005b836110c65760006110c8565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561113257600080fd5b505af1158015611146573d6000803e3d6000fd5b5050505061116c8a60c001518b61010001518c6080015161ffff168d602001518c611733565b9750876000036111a8576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84156112d95786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561121d57600080fd5b505af1158015611231573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611293576040519150601f19603f3d011682016040523d82523d6000602084013e611298565b606091505b50509050806112d3576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061130d565b61130d8a60400151898c610100015173ffffffffffffffffffffffffffffffffffffffff166116a19092919063ffffffff16565b8461131d57896101000151611320565b60005b73ffffffffffffffffffffffffffffffffffffffff1686611345578a60e00151611348565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c6040516113b7929190918252602082015260400190565b60405180910390a45050505050505092915050565b6060806000600184516113df91906120cd565b90508067ffffffffffffffff8111156113fa576113fa611d2b565b604051908082528060200260200182016040528015611423578160200160208202803683370190505b509250835167ffffffffffffffff81111561144057611440611d2b565b604051908082528060200260200182016040528015611469578160200160208202803683370190505b5091508482600081518110611480576114806120e0565b60200260200101818152505060005b818110156116675760008582815181106114ab576114ab6120e0565b602002602001015190506000868360016114c5919061223d565b815181106114d5576114d56120e0565b602002602001015190506114ea8983836117ec565b8684815181106114fc576114fc6120e0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506000806115448b85856117ec565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561158e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b2919061226e565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16111561160d57905b896103e502826103e80201818b6103e502028161162c5761162c6122be565b049950898761163c87600161223d565b8151811061164c5761164c6120e0565b602090810291909101015250506001909201915061148f9050565b5050935093915050565b600061271061168083826122ed565b61168e9061ffff168561230f565b6116989190612326565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261172e908490611945565b505050565b60006107d084111561177a576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561178c575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156117c257606460328402046117c5565b60005b90508083038382146117dd576117dd8a8a8484611a54565b50505090910395945050505050565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115611826579091905b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085811b8216602084015284901b1660348201528490604801604051602081830303815290604052805190602001206040516020016119079291907fff00000000000000000000000000000000000000000000000000000000000000815260609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016600183015260158201527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120949350505050565b60006119a7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611b1c9092919063ffffffff16565b90508051600014806119c85750808060200190518101906119c89190612361565b61172e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611771565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611b2b8484600085611b33565b949350505050565b606082471015611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611771565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bee91906123ae565b60006040518083038185875af1925050503d8060008114611c2b576040519150601f19603f3d011682016040523d82523d6000602084013e611c30565b606091505b5091509150611c4187838387611c4c565b979650505050505050565b60608315611ce2578251600003611cdb5773ffffffffffffffffffffffffffffffffffffffff85163b611cdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611771565b5081611b2b565b611b2b8383815115611cf75781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177191906123ca565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715611d7e57611d7e611d2b565b60405290565b604051610120810167ffffffffffffffff81118282101715611d7e57611d7e611d2b565b803573ffffffffffffffffffffffffffffffffffffffff81168114611dcc57600080fd5b919050565b803561ffff81168114611dcc57600080fd5b803565ffffffffffff81168114611dcc57600080fd5b600082601f830112611e0a57600080fd5b8135602067ffffffffffffffff80831115611e2757611e27611d2b565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6a57611e6a611d2b565b604052938452858101830193838101925087851115611e8857600080fd5b83870191505b84821015611c4157611e9f82611da8565b83529183019190830190611e8e565b600060408284031215611ec057600080fd5b50919050565b60008060408385031215611ed957600080fd5b823567ffffffffffffffff80821115611ef157600080fd5b908401906101008287031215611f0657600080fd5b611f0e611d5a565b8235815260208301356020820152611f2860408401611da8565b6040820152611f3960608401611dd1565b6060820152611f4a60808401611dd1565b6080820152611f5b60a08401611de3565b60a0820152611f6c60c08401611da8565b60c082015260e083013582811115611f8357600080fd5b611f8f88828601611df9565b60e08301525093506020850135915080821115611fab57600080fd5b50611fb885828601611eae565b9150509250929050565b600080828403610140811215611fd757600080fd5b61012080821215611fe757600080fd5b611fef611d84565b9150843582526020850135602083015261200b60408601611da8565b604083015261201c60608601611dd1565b606083015261202d60808601611dd1565b608083015261203e60a08601611de3565b60a083015261204f60c08601611da8565b60c083015261206060e08601611da8565b60e0830152610100612073818701611da8565b9083015290925083013567ffffffffffffffff81111561209257600080fd5b611fb885828601611eae565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561169b5761169b61209e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261214457600080fd5b83018035915067ffffffffffffffff82111561215f57600080fd5b60200191503681900382131561217457600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b8082018082111561169b5761169b61209e565b80516dffffffffffffffffffffffffffff81168114611dcc57600080fd5b60008060006060848603121561228357600080fd5b61228c84612250565b925061229a60208501612250565b9150604084015163ffffffff811681146122b357600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b61ffff8281168282160390808211156123085761230861209e565b5092915050565b808202811582820484141761169b5761169b61209e565b60008261235c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561237357600080fd5b8151801515811461238357600080fd5b9392505050565b60005b838110156123a557818101518382015260200161238d565b50506000910152565b600082516123c081846020870161238a565b9190910192915050565b60208152600082518060208401526123e981604085016020870161238a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212205c2186193f26754a210d4ead3a4fd7d498dab0a801ab37d6db00bca51b76c6a364736f6c63430008130033", + "numDeployments": 17, + "solcInputHash": "b02a0ce4f8d2d52325669cdc01d21082", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmountOut\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"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\":\"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\":\"uniswapV2ExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV2ExactInputSingle\",\"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\":\"uniswapV2ExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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\\ncontract UniV2RouterFacet is IUniV2Router {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n /**\\n * NOTE: The tokens must already have been transferred to the pool\\n */\\n function uniswapV2ExactInputSingleInternal(\\n ExactInputSingleParams calldata params,\\n address pair\\n ) internal returns (uint256 amountOut) {\\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\\n\\n address tokenIn = params.tokenIn == address(0) ? address(s.weth) : params.tokenIn;\\n address tokenOut = params.tokenOut == address(0) ? address(s.weth) : params.tokenOut;\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\\n\\n if (tokenIn > 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 InsufficientOutputAmount();\\n }\\n\\n bool zeroForOne = tokenIn < 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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert ZeroAmountOut();\\n }\\n\\n if (params.tokenOut == address(0)) {\\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(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function uniswapV2ExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\\n\\n address pair = LibUniV2Router.pairFor(\\n s.uniswapV2Factory,\\n params.tokenIn == address(0) ? address(s.weth) : params.tokenIn,\\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\\n );\\n\\n if (params.tokenIn == address(0)) {\\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(address(s.weth)).safeTransfer(pair, params.amountIn);\\n } else {\\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, pair, params.amountIn);\\n }\\n\\n return uniswapV2ExactInputSingleInternal(params, pair);\\n }\\n\\n function uniswapV2ExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\\n\\n address pair = LibUniV2Router.pairFor(\\n s.uniswapV2Factory,\\n params.tokenIn,\\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\\n );\\n\\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 return uniswapV2ExactInputSingleInternal(params, pair);\\n }\\n\\n /**\\n * NOTE: The tokens must already have been transferred to the first pool\\n *\\n * The path should be rewritten so address(0) is replaced by the WETH address\\n */\\n function uniswapV2ExactInputInternal(\\n ExactInputParams calldata params,\\n address[] memory path,\\n address[] memory pairs,\\n uint256[] memory amounts\\n ) internal returns (uint256 amountOut) {\\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\\n\\n uint256 pathLengthMinusOne = params.path.length - 1;\\n\\n // Enforce minimum amount/max slippage\\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\\n revert InsufficientOutputAmount();\\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 = path[index] < path[indexPlusOne] ? true : false;\\n address to = index < 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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n path[pathLengthMinusOne],\\n params.feeBps,\\n params.amountOut,\\n amounts[pathLengthMinusOne]\\n );\\n\\n if (amountOut == 0) {\\n revert ZeroAmountOut();\\n }\\n\\n if (params.path[pathLengthMinusOne] == address(0)) {\\n // To ETH. 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(path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n params.path[0],\\n params.path[pathLengthMinusOne],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2ExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\\n\\n uint256 pathLengthMinusOne = params.path.length - 1;\\n address[] memory path = params.path;\\n\\n if (params.path[0] == address(0)) {\\n // From ETH\\n path[0] = address(s.weth);\\n }\\n\\n if (params.path[pathLengthMinusOne] == address(0)) {\\n // To ETH\\n path[pathLengthMinusOne] = address(s.weth);\\n }\\n\\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\\n s.uniswapV2Factory,\\n params.amountIn,\\n path\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (params.path[0] == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer WETH tokens to the first pool\\n IERC20(path[0]).safeTransfer(pairs[0], params.amountIn);\\n } else {\\n IERC20(path[0]).safeTransferFrom(msg.sender, pairs[0], params.amountIn);\\n }\\n\\n return uniswapV2ExactInputInternal(params, path, pairs, amounts);\\n }\\n\\n function uniswapV2ExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\\n\\n uint256 pathLengthMinusOne = params.path.length - 1;\\n address[] memory path = params.path;\\n\\n if (params.path[pathLengthMinusOne] == address(0)) {\\n // To ETH\\n path[pathLengthMinusOne] = address(s.weth);\\n }\\n\\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\\n s.uniswapV2Factory,\\n params.amountIn,\\n path\\n );\\n\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: 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 return uniswapV2ExactInputInternal(params, path, pairs, amounts);\\n }\\n}\\n\",\"keccak256\":\"0x9f5ef15bd933e401e7f447a5ebf7d481ade81d50e83cfab6abb2fe37b2622cdf\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Router.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Router is ILibStarVault, ILibWarp {\\n error EthTransferFailed();\\n error ZeroAmountOut();\\n error IncorrectEthValue();\\n error InsufficientOutputAmount();\\n error DeadlineExpired();\\n\\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 calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2ExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV2ExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2ExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x78671e954c3d2e6dd24c78f4e611d09c4f1790641c4f18b31238014b8279ee4d\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612a64806100206000396000f3fe60806040526004361061003f5760003560e01c806311e37b8d1461004457806316c17042146100765780633b58c7c21461008957806379e65c001461009c575b600080fd5b34801561005057600080fd5b5061006461005f36600461248a565b6100bc565b60405190815260200160405180910390f35b6100646100843660046124db565b610395565b61006461009736600461250b565b610652565b3480156100a857600080fd5b506100646100b7366004612540565b610b49565b7fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191e546000907fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c9082906101989073ffffffffffffffffffffffffffffffffffffffff16610130610100880160e0890161259a565b60006101446101208a016101008b0161259a565b73ffffffffffffffffffffffffffffffffffffffff16146101765761017161012089016101008a0161259a565b610f1d565b8454610100900473ffffffffffffffffffffffffffffffffffffffff16610f1d565b60038301546040805160e080820190925292935073ffffffffffffffffffffffffffffffffffffffff90911691632b67b570913391908190606082019081906101e8906101008e01908e0161259a565b73ffffffffffffffffffffffffffffffffffffffff90811682528c3516602082015260400161021d60c08d0160a08e016125d0565b65ffffffffffff90811682528b3516602091820152908252309082015260400161024d60c08b0160a08c016125d0565b65ffffffffffff16905261026460208901896125f8565b6040518563ffffffff1660e01b81526004016102839493929190612664565b600060405180830381600087803b15801561029d57600080fd5b505af11580156102b1573d6000803e3d6000fd5b50505050600382015473ffffffffffffffffffffffffffffffffffffffff166336c78516338388356102ea6101008b0160e08c0161259a565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561036857600080fd5b505af115801561037c573d6000803e3d6000fd5b5050505061038a8582611076565b925050505b92915050565b60006103a760c0830160a084016125d0565b65ffffffffffff164211156103e8576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191e547fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c906000906104eb9073ffffffffffffffffffffffffffffffffffffffff168261045b610100880160e0890161259a565b73ffffffffffffffffffffffffffffffffffffffff161461048c57610487610100870160e0880161259a565b6104aa565b8354610100900473ffffffffffffffffffffffffffffffffffffffff165b60006104be61012089016101008a0161259a565b73ffffffffffffffffffffffffffffffffffffffff1614610176576101716101208801610100890161259a565b90506000610500610100860160e0870161259a565b73ffffffffffffffffffffffffffffffffffffffff160361060a5734843514610555576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156105c157600080fd5b505af11580156105d5573d6000803e3d6000fd5b505084546106059350610100900473ffffffffffffffffffffffffffffffffffffffff1691508390508635611667565b610640565b61064033828635610622610100890160e08a0161259a565b73ffffffffffffffffffffffffffffffffffffffff16929190611740565b61064a8482611076565b949350505050565b600061066460c0830160a084016125d0565b65ffffffffffff164211156106a5576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c600060016106d760e0860186612726565b6106e29291506127bd565b905060006106f360e0860186612726565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201829052509394506107349250505060e0870187612726565b6000818110610745576107456127d0565b905060200201602081019061075a919061259a565b73ffffffffffffffffffffffffffffffffffffffff16036107e8578260000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16816000815181106107ad576107ad6127d0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f760e0870187612726565b84818110610807576108076127d0565b905060200201602081019061081c919061259a565b73ffffffffffffffffffffffffffffffffffffffff16036108a9578260000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681838151811061086e5761086e6127d0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b600283015460009081906108d59073ffffffffffffffffffffffffffffffffffffffff168835856117a4565b90925090506108f760208801356108f260808a0160608b016127ff565b611a49565b816001835161090691906127bd565b81518110610916576109166127d0565b60200260200101511015610956576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061096560e0890189612726565b6000818110610976576109766127d0565b905060200201602081019061098b919061259a565b73ffffffffffffffffffffffffffffffffffffffff1603610acd57348735146109e0576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610a4c57600080fd5b505af1158015610a60573d6000803e3d6000fd5b5050505050610ac882600081518110610a7b57610a7b6127d0565b6020026020010151886000013585600081518110610a9b57610a9b6127d0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116679092919063ffffffff16565b610b32565b610b323383600081518110610ae457610ae46127d0565b6020026020010151896000013586600081518110610b0457610b046127d0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611740909392919063ffffffff16565b610b3e87848484611a77565b979650505050505050565b60007fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c816001610b7c60e0870187612726565b610b879291506127bd565b90506000610b9860e0870187612726565b808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250939450610bd99250505060e0880188612726565b84818110610be957610be96127d0565b9050602002016020810190610bfe919061259a565b73ffffffffffffffffffffffffffffffffffffffff1603610c8b578260000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16818381518110610c5057610c506127d0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60028301546000908190610cb79073ffffffffffffffffffffffffffffffffffffffff168935856117a4565b60038701546040805160e08101909152865193955091935073ffffffffffffffffffffffffffffffffffffffff1691632b67b5709133918190606082019081908a90600090610d0857610d086127d0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000013573ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0016020810190610d5e91906125d0565b65ffffffffffff90811682528e35166020918201529082523090820152604001610d8e60c08e0160a08f016125d0565b65ffffffffffff169052610da560208c018c6125f8565b6040518563ffffffff1660e01b8152600401610dc49493929190612664565b600060405180830381600087803b158015610dde57600080fd5b505af1158015610df2573d6000803e3d6000fd5b5050506003860154835173ffffffffffffffffffffffffffffffffffffffff90911691506336c785169033908590600090610e2f57610e2f6127d0565b60209081029190910101518b35610e4960e08e018e612726565b6000818110610e5a57610e5a6127d0565b9050602002016020810190610e6f919061259a565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b158015610eed57600080fd5b505af1158015610f01573d6000803e3d6000fd5b50505050610f1188848484611a77565b98975050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115610f57579091905b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085811b8216602084015284901b1660348201528490604801604051602081830303815290604052805190602001206040516020016110389291907fff00000000000000000000000000000000000000000000000000000000000000815260609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016600183015260158201527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120949350505050565b60007fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c81806110ac610100870160e0880161259a565b73ffffffffffffffffffffffffffffffffffffffff16146110dd576110d8610100860160e0870161259a565b6110fb565b8154610100900473ffffffffffffffffffffffffffffffffffffffff165b90506000806111126101208801610100890161259a565b73ffffffffffffffffffffffffffffffffffffffff16146111445761113f6101208701610100880161259a565b611162565b8254610100900473ffffffffffffffffffffffffffffffffffffffff165b90506000808673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156111b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d69190612846565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16111561123157905b87356103e58181026103e8850201918302028161125057611250612896565b04955061126b60208901356108f260808b0160608c016127ff565b8610156112a4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16106112e05760006112e3565b60015b90508773ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261130c578861130f565b60005b8361131b57600061131d565b895b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561138757600080fd5b505af115801561139b573d6000803e3d6000fd5b506113d492506113b491505060e08b0160c08c0161259a565b856113c560a08d0160808e016127ff565b61ffff168c602001358b61206e565b965086600003611410576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114246101208b016101008c0161259a565b73ffffffffffffffffffffffffffffffffffffffff16036115775785546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156114ae57600080fd5b505af11580156114c2573d6000803e3d6000fd5b50600092506114da91505060608b0160408c0161259a565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611531576040519150601f19603f3d011682016040523d82523d6000602084013e611536565b606091505b5050905080611571576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506115a8565b6115a861158a60608b0160408c0161259a565b73ffffffffffffffffffffffffffffffffffffffff86169089611667565b6115ba6101208a016101008b0161259a565b73ffffffffffffffffffffffffffffffffffffffff166115e16101008b0160e08c0161259a565b73ffffffffffffffffffffffffffffffffffffffff1661160760e08c0160c08d0161259a565b604080518d358152602081018c905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a450505050505092915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261173b9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612127565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261179e9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016116b9565b50505050565b6060806000600184516117b791906127bd565b90508067ffffffffffffffff8111156117d2576117d26128c5565b6040519080825280602002602001820160405280156117fb578160200160208202803683370190505b509250835167ffffffffffffffff811115611818576118186128c5565b604051908082528060200260200182016040528015611841578160200160208202803683370190505b5091508482600081518110611858576118586127d0565b60200260200101818152505060005b81811015611a3f576000858281518110611883576118836127d0565b6020026020010151905060008683600161189d91906128f4565b815181106118ad576118ad6127d0565b602002602001015190506118c2898383610f1d565b8684815181106118d4576118d46127d0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060008061191c8b8585610f1d565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611966573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198a9190612846565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1611156119e557905b896103e502826103e80201818b6103e5020281611a0457611a04612896565b0499508987611a148760016128f4565b81518110611a2457611a246127d0565b60209081029190910101525050600190920191506118679050565b5050935093915050565b6000612710611a588382612907565b611a669061ffff1685612929565b611a709190612940565b9392505050565b60007fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c816001611aaa60e0890189612726565b611ab59291506127bd565b9050611acf60208801356108f260808a0160608b016127ff565b8460018651611ade91906127bd565b81518110611aee57611aee6127d0565b60200260200101511015611b2e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015611d1d576000611b468260016128f4565b90506000888281518110611b5c57611b5c6127d0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16898481518110611b8c57611b8c6127d0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611bb6576000611bb9565b60015b9050600060028a51611bcb91906127bd565b8410611bd75730611bf2565b888381518110611be957611be96127d0565b60200260200101515b9050888481518110611c0657611c066127d0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611c4d57898581518110611c4057611c406127d0565b6020026020010151611c50565b60005b84611c5c576000611c77565b8a8681518110611c6e57611c6e6127d0565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611cf757600080fd5b505af1158015611d0b573d6000803e3d6000fd5b50505050836001019350505050611b31565b50611d86611d3160e0890160c08a0161259a565b878381518110611d4357611d436127d0565b6020026020010151896080016020810190611d5e91906127ff565b61ffff168a60200135888681518110611d7957611d796127d0565b602002602001015161206e565b925082600003611dc2576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611dd160e0890189612726565b83818110611de157611de16127d0565b9050602002016020810190611df6919061259a565b73ffffffffffffffffffffffffffffffffffffffff1603611f495781546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810185905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b158015611e8057600080fd5b505af1158015611e94573d6000803e3d6000fd5b5060009250611eac9150506060890160408a0161259a565b73ffffffffffffffffffffffffffffffffffffffff168460405160006040518083038185875af1925050503d8060008114611f03576040519150601f19603f3d011682016040523d82523d6000602084013e611f08565b606091505b5050905080611f43576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611f6f565b611f6f611f5c6060890160408a0161259a565b84888481518110610a9b57610a9b6127d0565b611f7c60e0880188612726565b82818110611f8c57611f8c6127d0565b9050602002016020810190611fa1919061259a565b73ffffffffffffffffffffffffffffffffffffffff16611fc460e0890189612726565b6000818110611fd557611fd56127d0565b9050602002016020810190611fea919061259a565b73ffffffffffffffffffffffffffffffffffffffff1661201060e08a0160c08b0161259a565b604080518b3581526020810188905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a45050949350505050565b60006107d08411156120b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156120c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156120fd5760646032840204612100565b60005b9050808303838214612118576121188a8a8484612236565b50505090910395945050505050565b6000612189826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122fe9092919063ffffffff16565b90508051600014806121aa5750808060200190518101906121aa919061297b565b61173b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016120ac565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061064a8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161233291906129c1565b60006040518083038185875af1925050503d806000811461236f576040519150601f19603f3d011682016040523d82523d6000602084013e612374565b606091505b5091509150610b3e878383876060831561241657825160000361240f5773ffffffffffffffffffffffffffffffffffffffff85163b61240f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016120ac565b508161064a565b61064a838381511561242b5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120ac91906129dd565b6000610120828403121561247257600080fd5b50919050565b60006040828403121561247257600080fd5b600080610140838503121561249e57600080fd5b6124a8848461245f565b915061012083013567ffffffffffffffff8111156124c557600080fd5b6124d185828601612478565b9150509250929050565b600061012082840312156124ee57600080fd5b611a70838361245f565b6000610100828403121561247257600080fd5b60006020828403121561251d57600080fd5b813567ffffffffffffffff81111561253457600080fd5b61064a848285016124f8565b6000806040838503121561255357600080fd5b823567ffffffffffffffff8082111561256b57600080fd5b612577868387016124f8565b9350602085013591508082111561258d57600080fd5b506124d185828601612478565b6000602082840312156125ac57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114611a7057600080fd5b6000602082840312156125e257600080fd5b813565ffffffffffff81168114611a7057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261262d57600080fd5b83018035915067ffffffffffffffff82111561264857600080fd5b60200191503681900382131561265d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261275b57600080fd5b83018035915067ffffffffffffffff82111561277657600080fd5b6020019150600581901b360382131561265d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561038f5761038f61278e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561281157600080fd5b813561ffff81168114611a7057600080fd5b80516dffffffffffffffffffffffffffff8116811461284157600080fd5b919050565b60008060006060848603121561285b57600080fd5b61286484612823565b925061287260208501612823565b9150604084015163ffffffff8116811461288b57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8082018082111561038f5761038f61278e565b61ffff8281168282160390808211156129225761292261278e565b5092915050565b808202811582820484141761038f5761038f61278e565b600082612976577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561298d57600080fd5b81518015158114611a7057600080fd5b60005b838110156129b85781810151838201526020016129a0565b50506000910152565b600082516129d381846020870161299d565b9190910192915050565b60208152600082518060208401526129fc81604085016020870161299d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212206baaaa0ce060ae55ddde9e5690ed77da5fde99c9b09c02bec92c3f385ee9134064736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003f5760003560e01c806311e37b8d1461004457806316c17042146100765780633b58c7c21461008957806379e65c001461009c575b600080fd5b34801561005057600080fd5b5061006461005f36600461248a565b6100bc565b60405190815260200160405180910390f35b6100646100843660046124db565b610395565b61006461009736600461250b565b610652565b3480156100a857600080fd5b506100646100b7366004612540565b610b49565b7fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191e546000907fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c9082906101989073ffffffffffffffffffffffffffffffffffffffff16610130610100880160e0890161259a565b60006101446101208a016101008b0161259a565b73ffffffffffffffffffffffffffffffffffffffff16146101765761017161012089016101008a0161259a565b610f1d565b8454610100900473ffffffffffffffffffffffffffffffffffffffff16610f1d565b60038301546040805160e080820190925292935073ffffffffffffffffffffffffffffffffffffffff90911691632b67b570913391908190606082019081906101e8906101008e01908e0161259a565b73ffffffffffffffffffffffffffffffffffffffff90811682528c3516602082015260400161021d60c08d0160a08e016125d0565b65ffffffffffff90811682528b3516602091820152908252309082015260400161024d60c08b0160a08c016125d0565b65ffffffffffff16905261026460208901896125f8565b6040518563ffffffff1660e01b81526004016102839493929190612664565b600060405180830381600087803b15801561029d57600080fd5b505af11580156102b1573d6000803e3d6000fd5b50505050600382015473ffffffffffffffffffffffffffffffffffffffff166336c78516338388356102ea6101008b0160e08c0161259a565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561036857600080fd5b505af115801561037c573d6000803e3d6000fd5b5050505061038a8582611076565b925050505b92915050565b60006103a760c0830160a084016125d0565b65ffffffffffff164211156103e8576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191e547fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c906000906104eb9073ffffffffffffffffffffffffffffffffffffffff168261045b610100880160e0890161259a565b73ffffffffffffffffffffffffffffffffffffffff161461048c57610487610100870160e0880161259a565b6104aa565b8354610100900473ffffffffffffffffffffffffffffffffffffffff165b60006104be61012089016101008a0161259a565b73ffffffffffffffffffffffffffffffffffffffff1614610176576101716101208801610100890161259a565b90506000610500610100860160e0870161259a565b73ffffffffffffffffffffffffffffffffffffffff160361060a5734843514610555576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156105c157600080fd5b505af11580156105d5573d6000803e3d6000fd5b505084546106059350610100900473ffffffffffffffffffffffffffffffffffffffff1691508390508635611667565b610640565b61064033828635610622610100890160e08a0161259a565b73ffffffffffffffffffffffffffffffffffffffff16929190611740565b61064a8482611076565b949350505050565b600061066460c0830160a084016125d0565b65ffffffffffff164211156106a5576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c600060016106d760e0860186612726565b6106e29291506127bd565b905060006106f360e0860186612726565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201829052509394506107349250505060e0870187612726565b6000818110610745576107456127d0565b905060200201602081019061075a919061259a565b73ffffffffffffffffffffffffffffffffffffffff16036107e8578260000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16816000815181106107ad576107ad6127d0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f760e0870187612726565b84818110610807576108076127d0565b905060200201602081019061081c919061259a565b73ffffffffffffffffffffffffffffffffffffffff16036108a9578260000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681838151811061086e5761086e6127d0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b600283015460009081906108d59073ffffffffffffffffffffffffffffffffffffffff168835856117a4565b90925090506108f760208801356108f260808a0160608b016127ff565b611a49565b816001835161090691906127bd565b81518110610916576109166127d0565b60200260200101511015610956576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061096560e0890189612726565b6000818110610976576109766127d0565b905060200201602081019061098b919061259a565b73ffffffffffffffffffffffffffffffffffffffff1603610acd57348735146109e0576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610a4c57600080fd5b505af1158015610a60573d6000803e3d6000fd5b5050505050610ac882600081518110610a7b57610a7b6127d0565b6020026020010151886000013585600081518110610a9b57610a9b6127d0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116679092919063ffffffff16565b610b32565b610b323383600081518110610ae457610ae46127d0565b6020026020010151896000013586600081518110610b0457610b046127d0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611740909392919063ffffffff16565b610b3e87848484611a77565b979650505050505050565b60007fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c816001610b7c60e0870187612726565b610b879291506127bd565b90506000610b9860e0870187612726565b808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250939450610bd99250505060e0880188612726565b84818110610be957610be96127d0565b9050602002016020810190610bfe919061259a565b73ffffffffffffffffffffffffffffffffffffffff1603610c8b578260000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16818381518110610c5057610c506127d0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60028301546000908190610cb79073ffffffffffffffffffffffffffffffffffffffff168935856117a4565b60038701546040805160e08101909152865193955091935073ffffffffffffffffffffffffffffffffffffffff1691632b67b5709133918190606082019081908a90600090610d0857610d086127d0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000013573ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0016020810190610d5e91906125d0565b65ffffffffffff90811682528e35166020918201529082523090820152604001610d8e60c08e0160a08f016125d0565b65ffffffffffff169052610da560208c018c6125f8565b6040518563ffffffff1660e01b8152600401610dc49493929190612664565b600060405180830381600087803b158015610dde57600080fd5b505af1158015610df2573d6000803e3d6000fd5b5050506003860154835173ffffffffffffffffffffffffffffffffffffffff90911691506336c785169033908590600090610e2f57610e2f6127d0565b60209081029190910101518b35610e4960e08e018e612726565b6000818110610e5a57610e5a6127d0565b9050602002016020810190610e6f919061259a565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b158015610eed57600080fd5b505af1158015610f01573d6000803e3d6000fd5b50505050610f1188848484611a77565b98975050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115610f57579091905b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085811b8216602084015284901b1660348201528490604801604051602081830303815290604052805190602001206040516020016110389291907fff00000000000000000000000000000000000000000000000000000000000000815260609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016600183015260158201527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120949350505050565b60007fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c81806110ac610100870160e0880161259a565b73ffffffffffffffffffffffffffffffffffffffff16146110dd576110d8610100860160e0870161259a565b6110fb565b8154610100900473ffffffffffffffffffffffffffffffffffffffff165b90506000806111126101208801610100890161259a565b73ffffffffffffffffffffffffffffffffffffffff16146111445761113f6101208701610100880161259a565b611162565b8254610100900473ffffffffffffffffffffffffffffffffffffffff165b90506000808673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156111b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d69190612846565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16111561123157905b87356103e58181026103e8850201918302028161125057611250612896565b04955061126b60208901356108f260808b0160608c016127ff565b8610156112a4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16106112e05760006112e3565b60015b90508773ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261130c578861130f565b60005b8361131b57600061131d565b895b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561138757600080fd5b505af115801561139b573d6000803e3d6000fd5b506113d492506113b491505060e08b0160c08c0161259a565b856113c560a08d0160808e016127ff565b61ffff168c602001358b61206e565b965086600003611410576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114246101208b016101008c0161259a565b73ffffffffffffffffffffffffffffffffffffffff16036115775785546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156114ae57600080fd5b505af11580156114c2573d6000803e3d6000fd5b50600092506114da91505060608b0160408c0161259a565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611531576040519150601f19603f3d011682016040523d82523d6000602084013e611536565b606091505b5050905080611571576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506115a8565b6115a861158a60608b0160408c0161259a565b73ffffffffffffffffffffffffffffffffffffffff86169089611667565b6115ba6101208a016101008b0161259a565b73ffffffffffffffffffffffffffffffffffffffff166115e16101008b0160e08c0161259a565b73ffffffffffffffffffffffffffffffffffffffff1661160760e08c0160c08d0161259a565b604080518d358152602081018c905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a450505050505092915050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261173b9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612127565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261179e9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016116b9565b50505050565b6060806000600184516117b791906127bd565b90508067ffffffffffffffff8111156117d2576117d26128c5565b6040519080825280602002602001820160405280156117fb578160200160208202803683370190505b509250835167ffffffffffffffff811115611818576118186128c5565b604051908082528060200260200182016040528015611841578160200160208202803683370190505b5091508482600081518110611858576118586127d0565b60200260200101818152505060005b81811015611a3f576000858281518110611883576118836127d0565b6020026020010151905060008683600161189d91906128f4565b815181106118ad576118ad6127d0565b602002602001015190506118c2898383610f1d565b8684815181106118d4576118d46127d0565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060008061191c8b8585610f1d565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611966573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198a9190612846565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1611156119e557905b896103e502826103e80201818b6103e5020281611a0457611a04612896565b0499508987611a148760016128f4565b81518110611a2457611a246127d0565b60209081029190910101525050600190920191506118679050565b5050935093915050565b6000612710611a588382612907565b611a669061ffff1685612929565b611a709190612940565b9392505050565b60007fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c816001611aaa60e0890189612726565b611ab59291506127bd565b9050611acf60208801356108f260808a0160608b016127ff565b8460018651611ade91906127bd565b81518110611aee57611aee6127d0565b60200260200101511015611b2e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015611d1d576000611b468260016128f4565b90506000888281518110611b5c57611b5c6127d0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16898481518110611b8c57611b8c6127d0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611bb6576000611bb9565b60015b9050600060028a51611bcb91906127bd565b8410611bd75730611bf2565b888381518110611be957611be96127d0565b60200260200101515b9050888481518110611c0657611c066127d0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611c4d57898581518110611c4057611c406127d0565b6020026020010151611c50565b60005b84611c5c576000611c77565b8a8681518110611c6e57611c6e6127d0565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611cf757600080fd5b505af1158015611d0b573d6000803e3d6000fd5b50505050836001019350505050611b31565b50611d86611d3160e0890160c08a0161259a565b878381518110611d4357611d436127d0565b6020026020010151896080016020810190611d5e91906127ff565b61ffff168a60200135888681518110611d7957611d796127d0565b602002602001015161206e565b925082600003611dc2576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611dd160e0890189612726565b83818110611de157611de16127d0565b9050602002016020810190611df6919061259a565b73ffffffffffffffffffffffffffffffffffffffff1603611f495781546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810185905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b158015611e8057600080fd5b505af1158015611e94573d6000803e3d6000fd5b5060009250611eac9150506060890160408a0161259a565b73ffffffffffffffffffffffffffffffffffffffff168460405160006040518083038185875af1925050503d8060008114611f03576040519150601f19603f3d011682016040523d82523d6000602084013e611f08565b606091505b5050905080611f43576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611f6f565b611f6f611f5c6060890160408a0161259a565b84888481518110610a9b57610a9b6127d0565b611f7c60e0880188612726565b82818110611f8c57611f8c6127d0565b9050602002016020810190611fa1919061259a565b73ffffffffffffffffffffffffffffffffffffffff16611fc460e0890189612726565b6000818110611fd557611fd56127d0565b9050602002016020810190611fea919061259a565b73ffffffffffffffffffffffffffffffffffffffff1661201060e08a0160c08b0161259a565b604080518b3581526020810188905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a45050949350505050565b60006107d08411156120b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156120c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156120fd5760646032840204612100565b60005b9050808303838214612118576121188a8a8484612236565b50505090910395945050505050565b6000612189826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122fe9092919063ffffffff16565b90508051600014806121aa5750808060200190518101906121aa919061297b565b61173b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016120ac565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061064a8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161233291906129c1565b60006040518083038185875af1925050503d806000811461236f576040519150601f19603f3d011682016040523d82523d6000602084013e612374565b606091505b5091509150610b3e878383876060831561241657825160000361240f5773ffffffffffffffffffffffffffffffffffffffff85163b61240f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016120ac565b508161064a565b61064a838381511561242b5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120ac91906129dd565b6000610120828403121561247257600080fd5b50919050565b60006040828403121561247257600080fd5b600080610140838503121561249e57600080fd5b6124a8848461245f565b915061012083013567ffffffffffffffff8111156124c557600080fd5b6124d185828601612478565b9150509250929050565b600061012082840312156124ee57600080fd5b611a70838361245f565b6000610100828403121561247257600080fd5b60006020828403121561251d57600080fd5b813567ffffffffffffffff81111561253457600080fd5b61064a848285016124f8565b6000806040838503121561255357600080fd5b823567ffffffffffffffff8082111561256b57600080fd5b612577868387016124f8565b9350602085013591508082111561258d57600080fd5b506124d185828601612478565b6000602082840312156125ac57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114611a7057600080fd5b6000602082840312156125e257600080fd5b813565ffffffffffff81168114611a7057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261262d57600080fd5b83018035915067ffffffffffffffff82111561264857600080fd5b60200191503681900382131561265d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261275b57600080fd5b83018035915067ffffffffffffffff82111561277657600080fd5b6020019150600581901b360382131561265d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561038f5761038f61278e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561281157600080fd5b813561ffff81168114611a7057600080fd5b80516dffffffffffffffffffffffffffff8116811461284157600080fd5b919050565b60008060006060848603121561285b57600080fd5b61286484612823565b925061287260208501612823565b9150604084015163ffffffff8116811461288b57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8082018082111561038f5761038f61278e565b61ffff8281168282160390808211156129225761292261278e565b5092915050565b808202811582820484141761038f5761038f61278e565b600082612976577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561298d57600080fd5b81518015158114611a7057600080fd5b60005b838110156129b85781810151838201526020016129a0565b50506000910152565b600082516129d381846020870161299d565b9190910192915050565b60208152600082518060208401526129fc81604085016020870161299d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212206baaaa0ce060ae55ddde9e5690ed77da5fde99c9b09c02bec92c3f385ee9134064736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/UniV3Callback.json b/packages/hardhat/deployments/mainnet/UniV3Callback.json index b42463b4..c8cb7124 100644 --- a/packages/hardhat/deployments/mainnet/UniV3Callback.json +++ b/packages/hardhat/deployments/mainnet/UniV3Callback.json @@ -1,5 +1,5 @@ { - "address": "0x5f0a509cE9DF04b8F74BC0304c2acc7de240BbFe", + "address": "0x11B469680df7bdA2Bf5dA4fd28df8dBFaE905de6", "abi": [ { "inputs": [], @@ -122,28 +122,28 @@ "type": "function" } ], - "transactionHash": "0xc5360b5591f6d36e84a5c381d6da024c76a77dd1537f438ab85865b368d1589c", + "transactionHash": "0x2b6e4bb9cdadf18098882987330a44ce2c97949c40b5a5fe996a7b223658a916", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x5f0a509cE9DF04b8F74BC0304c2acc7de240BbFe", - "transactionIndex": 128, - "gasUsed": "490897", + "contractAddress": "0x11B469680df7bdA2Bf5dA4fd28df8dBFaE905de6", + "transactionIndex": 28, + "gasUsed": "548175", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x9e6e8ed30f47869c3cce2dfba43c8510363234c472706dc6a5e0166a2ad57509", - "transactionHash": "0xc5360b5591f6d36e84a5c381d6da024c76a77dd1537f438ab85865b368d1589c", + "blockHash": "0xa568e451725aeb11e4b597097dd4ff0dc4e37bb15f935f76750c2f3c4e341961", + "transactionHash": "0x2b6e4bb9cdadf18098882987330a44ce2c97949c40b5a5fe996a7b223658a916", "logs": [], - "blockNumber": 18375621, - "cumulativeGasUsed": "10802958", + "blockNumber": 18511155, + "cumulativeGasUsed": "2253588", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 10, - "solcInputHash": "4a9aead708515414ed961374f1d066ed", - "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\":\"pancakeV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"ramsesV2SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swapCallback\",\"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\"},\"pancakeV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"ramsesV2SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"swapCallback(int256,int256,bytes)\":{\"notice\":\"KyperSwap V2 callback 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 /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * KyperSwap V2 callback\\n * NOTE: None of these arguments can be trusted\\n */\\n function swapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x85ecd0df604a102bbc22cbcfd07afec90fd4abb25b8fac2ce0bda48ba5663f82\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107f7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610687565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d5490911692820192909252903090036101c057805160408201516101bb9173ffffffffffffffffffffffffffffffffffffffff9091169033906102d2565b610288565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561026f57600080fd5b505af1158015610283573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261035f908490610364565b505050565b60006103c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104789092919063ffffffff16565b90508051600014806103e75750808060200190518101906103e79190610707565b61035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610487848460008561048f565b949350505050565b606082471015610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046f565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161054a9190610754565b60006040518083038185875af1925050503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d878383876105a8565b979650505050505050565b6060831561063e5782516000036106375773ffffffffffffffffffffffffffffffffffffffff85163b610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046f565b5081610487565b61048783838151156106535781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046f9190610770565b6000806000806060858703121561069d57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156106c357600080fd5b818701915087601f8301126106d757600080fd5b8135818111156106e657600080fd5b8860208285010111156106f857600080fd5b95989497505060200194505050565b60006020828403121561071957600080fd5b8151801515811461072957600080fd5b9392505050565b60005b8381101561074b578181015183820152602001610733565b50506000910152565b60008251610766818460208701610730565b9190910192915050565b602081526000825180602084015261078f816040850160208701610730565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e0c3a5ea77a59d4a136519a3fb790277ee65b84323dca008c9268c0208c1cb4364736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610687565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d5490911692820192909252903090036101c057805160408201516101bb9173ffffffffffffffffffffffffffffffffffffffff9091169033906102d2565b610288565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561026f57600080fd5b505af1158015610283573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261035f908490610364565b505050565b60006103c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104789092919063ffffffff16565b90508051600014806103e75750808060200190518101906103e79190610707565b61035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610487848460008561048f565b949350505050565b606082471015610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046f565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161054a9190610754565b60006040518083038185875af1925050503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d878383876105a8565b979650505050505050565b6060831561063e5782516000036106375773ffffffffffffffffffffffffffffffffffffffff85163b610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046f565b5081610487565b61048783838151156106535781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046f9190610770565b6000806000806060858703121561069d57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156106c357600080fd5b818701915087601f8301126106d757600080fd5b8135818111156106e657600080fd5b8860208285010111156106f857600080fd5b95989497505060200194505050565b60006020828403121561071957600080fd5b8151801515811461072957600080fd5b9392505050565b60005b8381101561074b578181015183820152602001610733565b50506000910152565b60008251610766818460208701610730565b9190910192915050565b602081526000825180602084015261078f816040850160208701610730565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e0c3a5ea77a59d4a136519a3fb790277ee65b84323dca008c9268c0208c1cb4364736f6c63430008130033", + "numDeployments": 11, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "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\":\"pancakeV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"ramsesV2SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swapCallback\",\"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\"},\"pancakeV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"ramsesV2SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"swapCallback(int256,int256,bytes)\":{\"notice\":\"KyperSwap V2 callback 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 if (callback.usePermit == 1) {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n } else {\\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\\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 /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * KyperSwap V2 callback\\n * NOTE: None of these arguments can be trusted\\n */\\n function swapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xe3eb6dae32a233cc02e3aa833b2a7bac774a3c9c2c11f6d8feae8745d976f4b6\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610903806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610793565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e546060820152903090036101e757805160408201516101e29173ffffffffffffffffffffffffffffffffffffffff909116903390610339565b6102ef565b80606001516001036102bf577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156102a257600080fd5b505af11580156102b6573d6000803e3d6000fd5b505050506102ef565b6020810151815160408301516102ef9273ffffffffffffffffffffffffffffffffffffffff909116913390610412565b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261040d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610470565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526100899085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161038b565b60006104d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166105849092919063ffffffff16565b90508051600014806104f35750808060200190518101906104f39190610813565b61040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610593848460008561059b565b949350505050565b60608247101561062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161057b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106569190610860565b60006040518083038185875af1925050503d8060008114610693576040519150601f19603f3d011682016040523d82523d6000602084013e610698565b606091505b50915091506106a9878383876106b4565b979650505050505050565b6060831561074a5782516000036107435773ffffffffffffffffffffffffffffffffffffffff85163b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057b565b5081610593565b610593838381511561075f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b919061087c565b600080600080606085870312156107a957600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156107cf57600080fd5b818701915087601f8301126107e357600080fd5b8135818111156107f257600080fd5b88602082850101111561080457600080fd5b95989497505060200194505050565b60006020828403121561082557600080fd5b8151801515811461083557600080fd5b9392505050565b60005b8381101561085757818101518382015260200161083f565b50506000910152565b6000825161087281846020870161083c565b9190910192915050565b602081526000825180602084015261089b81604085016020870161083c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bd61054b7d7be6361f4cde7d339ff2b4e90fc18022d2e43caaa86ef48c70f7df64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610793565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e546060820152903090036101e757805160408201516101e29173ffffffffffffffffffffffffffffffffffffffff909116903390610339565b6102ef565b80606001516001036102bf577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156102a257600080fd5b505af11580156102b6573d6000803e3d6000fd5b505050506102ef565b6020810151815160408301516102ef9273ffffffffffffffffffffffffffffffffffffffff909116913390610412565b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261040d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610470565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526100899085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161038b565b60006104d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166105849092919063ffffffff16565b90508051600014806104f35750808060200190518101906104f39190610813565b61040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610593848460008561059b565b949350505050565b60608247101561062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161057b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106569190610860565b60006040518083038185875af1925050503d8060008114610693576040519150601f19603f3d011682016040523d82523d6000602084013e610698565b606091505b50915091506106a9878383876106b4565b979650505050505050565b6060831561074a5782516000036107435773ffffffffffffffffffffffffffffffffffffffff85163b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057b565b5081610593565b610593838381511561075f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b919061087c565b600080600080606085870312156107a957600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156107cf57600080fd5b818701915087601f8301126107e357600080fd5b8135818111156107f257600080fd5b88602082850101111561080457600080fd5b95989497505060200194505050565b60006020828403121561082557600080fd5b8151801515811461083557600080fd5b9392505050565b60005b8381101561085757818101518382015260200161083f565b50506000910152565b6000825161087281846020870161083c565b9190910192915050565b602081526000825180602084015261089b81604085016020870161083c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bd61054b7d7be6361f4cde7d339ff2b4e90fc18022d2e43caaa86ef48c70f7df64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/UniV3Like.json b/packages/hardhat/deployments/mainnet/UniV3Like.json index 72f8cb9c..ab8714e3 100644 --- a/packages/hardhat/deployments/mainnet/UniV3Like.json +++ b/packages/hardhat/deployments/mainnet/UniV3Like.json @@ -1,5 +1,5 @@ { - "address": "0x57F1160A3aa52dd0CD42c8fB1D1Ab371F548A943", + "address": "0x65fa5Aab4B88D928cDaA122E86298c1d39106A9a", "abi": [ { "inputs": [], @@ -136,6 +136,72 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV3LikeExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -208,7 +274,78 @@ "type": "tuple" } ], - "name": "uniswapV3LikeExactInput", + "name": "uniswapV3LikeExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV3LikeExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -296,7 +433,7 @@ "type": "tuple" } ], - "name": "uniswapV3LikeExactInputSingle", + "name": "uniswapV3LikeExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -304,32 +441,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0x2b6d7575169538a9055c8ce62525d7ed90e09aba6d617d131111401b5cb8f224", + "transactionHash": "0xb08ddeb0ed724ed03042dd765c837ab974d10d50e7b8c631d37d14bcf1a1a43f", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x57F1160A3aa52dd0CD42c8fB1D1Ab371F548A943", - "transactionIndex": 74, - "gasUsed": "2039685", + "contractAddress": "0x65fa5Aab4B88D928cDaA122E86298c1d39106A9a", + "transactionIndex": 33, + "gasUsed": "2136257", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x8a20a23fd7110b0965ad3c7367bf488f024be063b82910f23d0eb9929b5188d4", - "transactionHash": "0x2b6d7575169538a9055c8ce62525d7ed90e09aba6d617d131111401b5cb8f224", + "blockHash": "0x3b5826a1859388f6de3b08423af2b4803beb6bef939234cc88d9172777e6f582", + "transactionHash": "0xb08ddeb0ed724ed03042dd765c837ab974d10d50e7b8c631d37d14bcf1a1a43f", "logs": [], - "blockNumber": 18383619, - "cumulativeGasUsed": "7284977", + "blockNumber": 18511169, + "cumulativeGasUsed": "4437911", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 12, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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/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 {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokens[0],\\n isToEth ? address(0) : params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0778264b402de681401a9d1ca9ee9e1d313e2075b7d853b1504704a605ba6c23\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\\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\":\"0x61677478daa5f86ad18959bbe4a13b95a997853f844642be3f6eb54d6ab9a772\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612421806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611de2565b610066565b60405190815260200160405180910390f35b610041610061366004611f8f565b6109f6565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029291906120a9565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff1681525089806020019061045191906120c2565b6040518563ffffffff1660e01b8152600401610470949392919061212e565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e91906121f0565b9150508061057b90612243565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906121f0565b50905061066381612243565b9550505b61066f61173b565b610682876101000151886060015161179b565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906120a9565b9050828110806107685750610765868461227b565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c188602001518960e001518a6040015161ffff168b61010001518a6117cb565b95508315610910577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108ca576040519150601f19603f3d011682016040523d82523d6000602084013e6108cf565b606091505b505090508061090a576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061093a565b875160e089015161093a9173ffffffffffffffffffffffffffffffffffffffff9091169088611884565b83610949578760e0015161094c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685610971578860c00151610974565b60005b73ffffffffffffffffffffffffffffffffffffffff16896020015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38b608001518a6040516109e3929190918252602082015260400190565b60405180910390a4505050505092915050565b60008260a0015165ffffffffffff16421115610a3e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e0840151805160009182918290610a5f57610a5f61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e001518481518110610aaf57610aaf61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610add5733610adf565b305b90508215610bfd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610b3b57610b3b61228e565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610b9a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b5050505050505b8115610c90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610c5557610c5561228e565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610ca857610ca861228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906120a9565b88519650905083610ed3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610ddb57610ddb61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610e8191906120c2565b6040518563ffffffff1660e01b8152600401610ea0949392919061212e565b600060405180830381600087803b158015610eba57600080fd5b505af1158015610ece573d6000803e3d6000fd5b505050505b60005b858110156111c457600081600101905060008a60e001518281518110610efe57610efe61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610f3257610f3261228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610fbf60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610f9957610f9961228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b80156110b65760008b61010001518481518110610fde57610fde61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a191906121f0565b915050806110ae90612243565b9950506111b1565b60008b610100015184815181106110cf576110cf61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906121f0565b5090506111ad81612243565b9950505b6111b961173b565b503093509050610ed6565b506111d386896060015161179b565b86101561120c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e0015186815181106112245761122461228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561129a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112be91906120a9565b9050818110806112d657506112d3878361227b565b81105b1561130d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113478960c001518a60e00151888151811061132b5761132b61228e565b60200260200101518b6080015161ffff168c602001518b6117cb565b96508315611496577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156113da57600080fd5b505af11580156113ee573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611450576040519150601f19603f3d011682016040523d82523d6000602084013e611455565b606091505b5050905080611490576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506114e2565b6114e28960400151888b60e0015189815181106114b5576114b561228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166118849092919063ffffffff16565b8361150a578860e0015186815181106114fd576114fd61228e565b602002602001015161150d565b60005b73ffffffffffffffffffffffffffffffffffffffff168561154c578960e0015160008151811061153f5761153f61228e565b602002602001015161154f565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b6040516115be929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611630576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611799576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60006127106117aa83826122bd565b6117b89061ffff16856122df565b6117c291906122f6565b90505b92915050565b60006107d0841115611812576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611824575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561185a576064603284020461185d565b60005b9050808303838214611875576118758a8a8484611916565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526119119084906119de565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611a40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611aed9092919063ffffffff16565b9050805160001480611a61575080806020019051810190611a619190612331565b611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611809565b6060611afc8484600085611b04565b949350505050565b606082471015611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611809565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbf919061237e565b60006040518083038185875af1925050503d8060008114611bfc576040519150601f19603f3d011682016040523d82523d6000602084013e611c01565b606091505b5091509150611c1287838387611c1d565b979650505050505050565b60608315611cb3578251600003611cac5773ffffffffffffffffffffffffffffffffffffffff85163b611cac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611809565b5081611afc565b611afc8383815115611cc85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611809919061239a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b60405290565b604051610120810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d9d57600080fd5b919050565b803561ffff81168114611d9d57600080fd5b803565ffffffffffff81168114611d9d57600080fd5b600060408284031215611ddc57600080fd5b50919050565b600080828403610160811215611df757600080fd5b61014080821215611e0757600080fd5b611e0f611d2b565b9150611e1a85611d79565b8252611e2860208601611d79565b6020830152611e3960408601611da2565b6040830152611e4a60608601611da2565b606083015260808501356080830152611e6560a08601611db4565b60a0830152611e7660c08601611d79565b60c0830152611e8760e08601611d79565b60e08301526101008581013590830152610120611ea5818701611d79565b9083015290925083013567ffffffffffffffff811115611ec457600080fd5b611ed085828601611dca565b9150509250929050565b600082601f830112611eeb57600080fd5b8135602067ffffffffffffffff80831115611f0857611f08611cfc565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611f4b57611f4b611cfc565b604052938452858101830193838101925087851115611f6957600080fd5b83870191505b84821015611c1257611f8082611d79565b83529183019190830190611f6f565b60008060408385031215611fa257600080fd5b823567ffffffffffffffff80821115611fba57600080fd5b908401906101208287031215611fcf57600080fd5b611fd7611d55565b8235815260208301356020820152611ff160408401611d79565b604082015261200260608401611da2565b606082015261201360808401611da2565b608082015261202460a08401611db4565b60a082015261203560c08401611d79565b60c082015260e08301358281111561204c57600080fd5b61205888828601611eda565b60e083015250610100808401358381111561207257600080fd5b61207e89828701611eda565b82840152505080945050602085013591508082111561209c57600080fd5b50611ed085828601611dca565b6000602082840312156120bb57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120f757600080fd5b83018035915067ffffffffffffffff82111561211257600080fd5b60200191503681900382131561212757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561220357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361227457612274612214565b5060000390565b808201808211156117c5576117c5612214565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156122d8576122d8612214565b5092915050565b80820281158282048414176117c5576117c5612214565b60008261232c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561234357600080fd5b8151801515811461235357600080fd5b9392505050565b60005b8381101561237557818101518382015260200161235d565b50506000910152565b6000825161239081846020870161235a565b9190910192915050565b60208152600082518060208401526123b981604085016020870161235a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220576050a04e57b56eff16cf6c316bc8966ab4a176dcea2edf74c13dd26adc111164736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611de2565b610066565b60405190815260200160405180910390f35b610041610061366004611f8f565b6109f6565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029291906120a9565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff1681525089806020019061045191906120c2565b6040518563ffffffff1660e01b8152600401610470949392919061212e565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e91906121f0565b9150508061057b90612243565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906121f0565b50905061066381612243565b9550505b61066f61173b565b610682876101000151886060015161179b565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906120a9565b9050828110806107685750610765868461227b565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c188602001518960e001518a6040015161ffff168b61010001518a6117cb565b95508315610910577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108ca576040519150601f19603f3d011682016040523d82523d6000602084013e6108cf565b606091505b505090508061090a576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061093a565b875160e089015161093a9173ffffffffffffffffffffffffffffffffffffffff9091169088611884565b83610949578760e0015161094c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685610971578860c00151610974565b60005b73ffffffffffffffffffffffffffffffffffffffff16896020015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38b608001518a6040516109e3929190918252602082015260400190565b60405180910390a4505050505092915050565b60008260a0015165ffffffffffff16421115610a3e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e0840151805160009182918290610a5f57610a5f61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e001518481518110610aaf57610aaf61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610add5733610adf565b305b90508215610bfd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610b3b57610b3b61228e565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610b9a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b5050505050505b8115610c90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610c5557610c5561228e565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610ca857610ca861228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906120a9565b88519650905083610ed3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610ddb57610ddb61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610e8191906120c2565b6040518563ffffffff1660e01b8152600401610ea0949392919061212e565b600060405180830381600087803b158015610eba57600080fd5b505af1158015610ece573d6000803e3d6000fd5b505050505b60005b858110156111c457600081600101905060008a60e001518281518110610efe57610efe61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610f3257610f3261228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610fbf60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610f9957610f9961228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b80156110b65760008b61010001518481518110610fde57610fde61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a191906121f0565b915050806110ae90612243565b9950506111b1565b60008b610100015184815181106110cf576110cf61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906121f0565b5090506111ad81612243565b9950505b6111b961173b565b503093509050610ed6565b506111d386896060015161179b565b86101561120c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e0015186815181106112245761122461228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561129a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112be91906120a9565b9050818110806112d657506112d3878361227b565b81105b1561130d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113478960c001518a60e00151888151811061132b5761132b61228e565b60200260200101518b6080015161ffff168c602001518b6117cb565b96508315611496577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156113da57600080fd5b505af11580156113ee573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611450576040519150601f19603f3d011682016040523d82523d6000602084013e611455565b606091505b5050905080611490576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506114e2565b6114e28960400151888b60e0015189815181106114b5576114b561228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166118849092919063ffffffff16565b8361150a578860e0015186815181106114fd576114fd61228e565b602002602001015161150d565b60005b73ffffffffffffffffffffffffffffffffffffffff168561154c578960e0015160008151811061153f5761153f61228e565b602002602001015161154f565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b6040516115be929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611630576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611799576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60006127106117aa83826122bd565b6117b89061ffff16856122df565b6117c291906122f6565b90505b92915050565b60006107d0841115611812576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611824575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561185a576064603284020461185d565b60005b9050808303838214611875576118758a8a8484611916565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526119119084906119de565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611a40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611aed9092919063ffffffff16565b9050805160001480611a61575080806020019051810190611a619190612331565b611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611809565b6060611afc8484600085611b04565b949350505050565b606082471015611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611809565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbf919061237e565b60006040518083038185875af1925050503d8060008114611bfc576040519150601f19603f3d011682016040523d82523d6000602084013e611c01565b606091505b5091509150611c1287838387611c1d565b979650505050505050565b60608315611cb3578251600003611cac5773ffffffffffffffffffffffffffffffffffffffff85163b611cac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611809565b5081611afc565b611afc8383815115611cc85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611809919061239a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b60405290565b604051610120810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d9d57600080fd5b919050565b803561ffff81168114611d9d57600080fd5b803565ffffffffffff81168114611d9d57600080fd5b600060408284031215611ddc57600080fd5b50919050565b600080828403610160811215611df757600080fd5b61014080821215611e0757600080fd5b611e0f611d2b565b9150611e1a85611d79565b8252611e2860208601611d79565b6020830152611e3960408601611da2565b6040830152611e4a60608601611da2565b606083015260808501356080830152611e6560a08601611db4565b60a0830152611e7660c08601611d79565b60c0830152611e8760e08601611d79565b60e08301526101008581013590830152610120611ea5818701611d79565b9083015290925083013567ffffffffffffffff811115611ec457600080fd5b611ed085828601611dca565b9150509250929050565b600082601f830112611eeb57600080fd5b8135602067ffffffffffffffff80831115611f0857611f08611cfc565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611f4b57611f4b611cfc565b604052938452858101830193838101925087851115611f6957600080fd5b83870191505b84821015611c1257611f8082611d79565b83529183019190830190611f6f565b60008060408385031215611fa257600080fd5b823567ffffffffffffffff80821115611fba57600080fd5b908401906101208287031215611fcf57600080fd5b611fd7611d55565b8235815260208301356020820152611ff160408401611d79565b604082015261200260608401611da2565b606082015261201360808401611da2565b608082015261202460a08401611db4565b60a082015261203560c08401611d79565b60c082015260e08301358281111561204c57600080fd5b61205888828601611eda565b60e083015250610100808401358381111561207257600080fd5b61207e89828701611eda565b82840152505080945050602085013591508082111561209c57600080fd5b50611ed085828601611dca565b6000602082840312156120bb57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120f757600080fd5b83018035915067ffffffffffffffff82111561211257600080fd5b60200191503681900382131561212757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561220357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361227457612274612214565b5060000390565b808201808211156117c5576117c5612214565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156122d8576122d8612214565b5092915050565b80820281158282048414176117c5576117c5612214565b60008261232c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561234357600080fd5b8151801515811461235357600080fd5b9392505050565b60005b8381101561237557818101518382015260200161235d565b50506000910152565b6000825161239081846020870161235a565b9190910192915050565b60208152600082518060208401526123b981604085016020870161235a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220576050a04e57b56eff16cf6c316bc8966ab4a176dcea2edf74c13dd26adc111164736f6c63430008130033", + "numDeployments": 13, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"name\":\"uniswapV3LikeExactInput\",\"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\":\"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\":\"uniswapV3LikeExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"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\":\"uniswapV3LikeExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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/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 {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\\n ExactInputSingleParams calldata params,\\n uint256 usePermit\\n ) internal returns (uint256 amountOut) {\\n bool isFromEth = params.tokenIn == address(0);\\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\\n\\n address tokenOut = params.tokenOut == address(0)\\n ? address(LibWarp.state().weth)\\n : params.tokenOut;\\n\\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = tokenIn < tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: tokenIn,\\n amount: params.amountIn,\\n usePermit: usePermit\\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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (params.tokenOut == address(0)) {\\n // To ETH, unwrap WETH\\n // TODO: This is read twice. Compare gas usage\\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(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn == address(0)) {\\n // From ETH, wrap it\\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\\n }\\n\\n function uniswapV3LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\\n }\\n\\n function uniswapV3LikeExactInputInternal(\\n ExactInputParams calldata params,\\n uint256 usePermit\\n ) internal returns (uint256 amountOut) {\\n uint256 poolLength = params.pools.length;\\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\\n address[] memory tokens = params.tokens;\\n\\n if (params.tokens[0] == address(0)) {\\n tokens[0] = address(LibWarp.state().weth);\\n }\\n\\n if (params.tokens[poolLength] == address(0)) {\\n tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: payer,\\n token: tokens[index],\\n amount: amountOut,\\n usePermit: usePermit\\n })\\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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (params.tokens[poolLength] == address(0)) {\\n // To ETH, unwrap\\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n params.tokens[0],\\n params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokens[0] == address(0)) {\\n // From ETH, wrap it\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n }\\n\\n return uniswapV3LikeExactInputInternal(params, 0);\\n }\\n\\n function uniswapV3LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 return uniswapV3LikeExactInputInternal(params, 1);\\n }\\n}\\n\",\"keccak256\":\"0x9e23653ffdee1ddba14b812d0ed30da1b28d009e139fef4562407e722f5c541f\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\\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 calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x1fbea0694f83750cccdc1e2e316bc7466e7d04e7342fd7d4359459f056d30a71\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506125e1806100206000396000f3fe60806040526004361061003e5760003560e01c80626ee8b6146100435780635576abd114610068578063a33aea141461007b578063cda932d11461009b575b600080fd5b610056610051366004612064565b6100bb565b60405190815260200160405180910390f35b6100566100763660046120ac565b61024f565b34801561008757600080fd5b506100566100963660046120db565b6103b2565b3480156100a757600080fd5b506100566100b636600461212c565b6104fc565b60006100cd60c0830160a08401612186565b65ffffffffffff1642111561010e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061011d60e08401846121ae565b600081811061012e5761012e61221d565b9050602002016020810190610143919061224c565b73ffffffffffffffffffffffffffffffffffffffff160361023e5734823514610198576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b50505050505b61024982600061065b565b92915050565b600061026160c0830160a08401612186565b65ffffffffffff164211156102a2576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b460e0840160c0850161224c565b73ffffffffffffffffffffffffffffffffffffffff16036103a7577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660808301353414610344576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561038c57600080fd5b505af11580156103a0573d6000803e3d6000fd5b5050505050505b610249826000611118565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b57091339181906060820190819061041a908b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff908116825260808b013516602082015260400161045260c08b0160a08c01612186565b65ffffffffffff9081168252893516602091820152908252309082015260400161048260c0890160a08a01612186565b65ffffffffffff1690526104996020870187612282565b6040518563ffffffff1660e01b81526004016104b894939291906122e7565b600060405180830381600087803b1580156104d257600080fd5b505af11580156104e6573d6000803e3d6000fd5b505050506104f5836001611118565b9392505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610561908b018b6121ae565b60008181106105725761057261221d565b9050602002016020810190610587919061224c565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016105bc60c08b0160a08c01612186565b65ffffffffffff908116825289351660209182015290825230908201526040016105ec60c0890160a08a01612186565b65ffffffffffff1690526106036020870187612282565b6040518563ffffffff1660e01b815260040161062294939291906122e7565b600060405180830381600087803b15801561063c57600080fd5b505af1158015610650573d6000803e3d6000fd5b505050506104f58360015b60008061066c6101008501856121ae565b9150600090508061068060e08701876121ae565b60008181106106915761069161221d565b90506020020160208101906106a6919061224c565b73ffffffffffffffffffffffffffffffffffffffff16146106c757336106c9565b305b905060006106da60e08701876121ae565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061071b9250505060e08801886121ae565b600081811061072c5761072c61221d565b9050602002016020810190610741919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036107e5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff9091169082906000906107aa576107aa61221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f460e08801886121ae565b858181106108045761080461221d565b9050602002016020810190610819919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036108be577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff909116908290859081106108835761088361221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008184815181106108d2576108d261221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c91906123a9565b87359550905060005b84811015610c8157600081600101905060008482815181106109995761099961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168584815181106109c9576109c961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610a5860405180608001604052808a81526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878681518110610a2c57610a2c61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018b815250611904565b8015610b61576000610a6e6101008c018c6121ae565b85818110610a7e57610a7e61221d565b9050602002016020810190610a93919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c91906123c2565b91505080610b5990612415565b985050610c6e565b6000610b716101008c018c6121ae565b85818110610b8157610b8161221d565b9050602002016020810190610b96919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5e91906123c2565b509050610c6a81612415565b9850505b610c76611a93565b503094509050610975565b50610c9b85610c9660808a0160608b0161244d565b611af3565b851015610cd4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828581518110610ce857610ce861221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8291906123a9565b905081811080610d9a5750610d978683612471565b81105b15610dd1576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e20610de460e08a0160c08b0161224c565b848781518110610df657610df661221d565b60200260200101518a6080016020810190610e11919061244d565b61ffff168b602001358a611b1a565b95506000610e3160e08a018a6121ae565b87818110610e4157610e4161221d565b9050602002016020810190610e56919061224c565b73ffffffffffffffffffffffffffffffffffffffff1603610fc5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b5060009250610f2891505060608a0160408b0161224c565b73ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610f7f576040519150601f19603f3d011682016040523d82523d6000602084013e610f84565b606091505b5050905080610fbf576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611018565b611018610fd860608a0160408b0161224c565b87858881518110610feb57610feb61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611bd39092919063ffffffff16565b61102560e08901896121ae565b868181106110355761103561221d565b905060200201602081019061104a919061224c565b73ffffffffffffffffffffffffffffffffffffffff1661106d60e08a018a6121ae565b600081811061107e5761107e61221d565b9050602002016020810190611093919061224c565b73ffffffffffffffffffffffffffffffffffffffff166110b960e08b0160c08c0161224c565b604080518c358152602081018b905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050505092915050565b6000808061112c60e0860160c0870161224c565b73ffffffffffffffffffffffffffffffffffffffff161490506000816111615761115c60e0860160c0870161224c565b61119a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b90506000806111b0610100880160e0890161224c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576111dc610100870160e0880161224c565b61121a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae91906123a9565b905060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610905061134860405180608001604052808a608001358152602001876113065733611308565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200189815250611904565b80156114335760006113626101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b013560448201526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e91906123c2565b9150508061142b90612415565b965050611522565b60006114476101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b0135604482015273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151291906123c2565b50905061151e81612415565b9650505b61152a611a93565b611543610100890135610c9660808b0160608c0161244d565b86101561157c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d91906123a9565b90508281108061162557506116228784612471565b81105b1561165c576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61169061166f60408b0160208c0161224c565b8561168060608d0160408e0161244d565b61ffff168c61010001358b611b1a565b965060006116a56101008b0160e08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1603611811577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d80600081146117cb576040519150601f19603f3d011682016040523d82523d6000602084013e6117d0565b606091505b505090508061180b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061183f565b61183f61182160208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff86169089611bd3565b6118506101008a0160e08b0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661187660e08b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661189c60408c0160208d0161224c565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c608001358b6040516118f0929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611962576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611af1576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612710611b028382612484565b611b109061ffff16856124a6565b6104f591906124bd565b60006107d0841115611b61576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611b73575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611ba95760646032840204611bac565b60005b9050808303838214611bc457611bc48a8a8484611c65565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611c60908490611d2d565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611d8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e3c9092919063ffffffff16565b9050805160001480611db0575080806020019051810190611db091906124f8565b611c60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611b58565b6060611e4b8484600085611e53565b949350505050565b606082471015611ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611b58565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611f0e919061253e565b60006040518083038185875af1925050503d8060008114611f4b576040519150601f19603f3d011682016040523d82523d6000602084013e611f50565b606091505b5091509150611f6187838387611f6c565b979650505050505050565b60608315612002578251600003611ffb5773ffffffffffffffffffffffffffffffffffffffff85163b611ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611b58565b5081611e4b565b611e4b83838151156120175781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b58919061255a565b6000610120828403121561205e57600080fd5b50919050565b60006020828403121561207657600080fd5b813567ffffffffffffffff81111561208d57600080fd5b611e4b8482850161204b565b6000610140828403121561205e57600080fd5b600061014082840312156120bf57600080fd5b6104f58383612099565b60006040828403121561205e57600080fd5b60008061016083850312156120ef57600080fd5b6120f98484612099565b915061014083013567ffffffffffffffff81111561211657600080fd5b612122858286016120c9565b9150509250929050565b6000806040838503121561213f57600080fd5b823567ffffffffffffffff8082111561215757600080fd5b6121638683870161204b565b9350602085013591508082111561217957600080fd5b50612122858286016120c9565b60006020828403121561219857600080fd5b813565ffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126121e357600080fd5b83018035915067ffffffffffffffff8211156121fe57600080fd5b6020019150600581901b360382131561221657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561225e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122b757600080fd5b83018035915067ffffffffffffffff8211156122d257600080fd5b60200191503681900382131561221657600080fd5b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156123bb57600080fd5b5051919050565b600080604083850312156123d557600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203612446576124466123e6565b5060000390565b60006020828403121561245f57600080fd5b813561ffff811681146104f557600080fd5b80820180821115610249576102496123e6565b61ffff82811682821603908082111561249f5761249f6123e6565b5092915050565b8082028115828204841417610249576102496123e6565b6000826124f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561250a57600080fd5b815180151581146104f557600080fd5b60005b8381101561253557818101518382015260200161251d565b50506000910152565b6000825161255081846020870161251a565b9190910192915050565b602081526000825180602084015261257981604085016020870161251a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122020ef15a82dfe9e15884ad78a08e0e295c6c50a821511c6e99799a1a517eefc3564736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003e5760003560e01c80626ee8b6146100435780635576abd114610068578063a33aea141461007b578063cda932d11461009b575b600080fd5b610056610051366004612064565b6100bb565b60405190815260200160405180910390f35b6100566100763660046120ac565b61024f565b34801561008757600080fd5b506100566100963660046120db565b6103b2565b3480156100a757600080fd5b506100566100b636600461212c565b6104fc565b60006100cd60c0830160a08401612186565b65ffffffffffff1642111561010e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061011d60e08401846121ae565b600081811061012e5761012e61221d565b9050602002016020810190610143919061224c565b73ffffffffffffffffffffffffffffffffffffffff160361023e5734823514610198576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b50505050505b61024982600061065b565b92915050565b600061026160c0830160a08401612186565b65ffffffffffff164211156102a2576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b460e0840160c0850161224c565b73ffffffffffffffffffffffffffffffffffffffff16036103a7577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660808301353414610344576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561038c57600080fd5b505af11580156103a0573d6000803e3d6000fd5b5050505050505b610249826000611118565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b57091339181906060820190819061041a908b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff908116825260808b013516602082015260400161045260c08b0160a08c01612186565b65ffffffffffff9081168252893516602091820152908252309082015260400161048260c0890160a08a01612186565b65ffffffffffff1690526104996020870187612282565b6040518563ffffffff1660e01b81526004016104b894939291906122e7565b600060405180830381600087803b1580156104d257600080fd5b505af11580156104e6573d6000803e3d6000fd5b505050506104f5836001611118565b9392505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610561908b018b6121ae565b60008181106105725761057261221d565b9050602002016020810190610587919061224c565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016105bc60c08b0160a08c01612186565b65ffffffffffff908116825289351660209182015290825230908201526040016105ec60c0890160a08a01612186565b65ffffffffffff1690526106036020870187612282565b6040518563ffffffff1660e01b815260040161062294939291906122e7565b600060405180830381600087803b15801561063c57600080fd5b505af1158015610650573d6000803e3d6000fd5b505050506104f58360015b60008061066c6101008501856121ae565b9150600090508061068060e08701876121ae565b60008181106106915761069161221d565b90506020020160208101906106a6919061224c565b73ffffffffffffffffffffffffffffffffffffffff16146106c757336106c9565b305b905060006106da60e08701876121ae565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061071b9250505060e08801886121ae565b600081811061072c5761072c61221d565b9050602002016020810190610741919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036107e5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff9091169082906000906107aa576107aa61221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f460e08801886121ae565b858181106108045761080461221d565b9050602002016020810190610819919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036108be577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff909116908290859081106108835761088361221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008184815181106108d2576108d261221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c91906123a9565b87359550905060005b84811015610c8157600081600101905060008482815181106109995761099961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168584815181106109c9576109c961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610a5860405180608001604052808a81526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878681518110610a2c57610a2c61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018b815250611904565b8015610b61576000610a6e6101008c018c6121ae565b85818110610a7e57610a7e61221d565b9050602002016020810190610a93919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c91906123c2565b91505080610b5990612415565b985050610c6e565b6000610b716101008c018c6121ae565b85818110610b8157610b8161221d565b9050602002016020810190610b96919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5e91906123c2565b509050610c6a81612415565b9850505b610c76611a93565b503094509050610975565b50610c9b85610c9660808a0160608b0161244d565b611af3565b851015610cd4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828581518110610ce857610ce861221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8291906123a9565b905081811080610d9a5750610d978683612471565b81105b15610dd1576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e20610de460e08a0160c08b0161224c565b848781518110610df657610df661221d565b60200260200101518a6080016020810190610e11919061244d565b61ffff168b602001358a611b1a565b95506000610e3160e08a018a6121ae565b87818110610e4157610e4161221d565b9050602002016020810190610e56919061224c565b73ffffffffffffffffffffffffffffffffffffffff1603610fc5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b5060009250610f2891505060608a0160408b0161224c565b73ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610f7f576040519150601f19603f3d011682016040523d82523d6000602084013e610f84565b606091505b5050905080610fbf576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611018565b611018610fd860608a0160408b0161224c565b87858881518110610feb57610feb61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611bd39092919063ffffffff16565b61102560e08901896121ae565b868181106110355761103561221d565b905060200201602081019061104a919061224c565b73ffffffffffffffffffffffffffffffffffffffff1661106d60e08a018a6121ae565b600081811061107e5761107e61221d565b9050602002016020810190611093919061224c565b73ffffffffffffffffffffffffffffffffffffffff166110b960e08b0160c08c0161224c565b604080518c358152602081018b905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050505092915050565b6000808061112c60e0860160c0870161224c565b73ffffffffffffffffffffffffffffffffffffffff161490506000816111615761115c60e0860160c0870161224c565b61119a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b90506000806111b0610100880160e0890161224c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576111dc610100870160e0880161224c565b61121a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae91906123a9565b905060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610905061134860405180608001604052808a608001358152602001876113065733611308565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200189815250611904565b80156114335760006113626101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b013560448201526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e91906123c2565b9150508061142b90612415565b965050611522565b60006114476101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b0135604482015273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151291906123c2565b50905061151e81612415565b9650505b61152a611a93565b611543610100890135610c9660808b0160608c0161244d565b86101561157c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d91906123a9565b90508281108061162557506116228784612471565b81105b1561165c576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61169061166f60408b0160208c0161224c565b8561168060608d0160408e0161244d565b61ffff168c61010001358b611b1a565b965060006116a56101008b0160e08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1603611811577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d80600081146117cb576040519150601f19603f3d011682016040523d82523d6000602084013e6117d0565b606091505b505090508061180b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061183f565b61183f61182160208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff86169089611bd3565b6118506101008a0160e08b0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661187660e08b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661189c60408c0160208d0161224c565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c608001358b6040516118f0929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611962576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611af1576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612710611b028382612484565b611b109061ffff16856124a6565b6104f591906124bd565b60006107d0841115611b61576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611b73575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611ba95760646032840204611bac565b60005b9050808303838214611bc457611bc48a8a8484611c65565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611c60908490611d2d565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611d8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e3c9092919063ffffffff16565b9050805160001480611db0575080806020019051810190611db091906124f8565b611c60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611b58565b6060611e4b8484600085611e53565b949350505050565b606082471015611ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611b58565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611f0e919061253e565b60006040518083038185875af1925050503d8060008114611f4b576040519150601f19603f3d011682016040523d82523d6000602084013e611f50565b606091505b5091509150611f6187838387611f6c565b979650505050505050565b60608315612002578251600003611ffb5773ffffffffffffffffffffffffffffffffffffffff85163b611ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611b58565b5081611e4b565b611e4b83838151156120175781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b58919061255a565b6000610120828403121561205e57600080fd5b50919050565b60006020828403121561207657600080fd5b813567ffffffffffffffff81111561208d57600080fd5b611e4b8482850161204b565b6000610140828403121561205e57600080fd5b600061014082840312156120bf57600080fd5b6104f58383612099565b60006040828403121561205e57600080fd5b60008061016083850312156120ef57600080fd5b6120f98484612099565b915061014083013567ffffffffffffffff81111561211657600080fd5b612122858286016120c9565b9150509250929050565b6000806040838503121561213f57600080fd5b823567ffffffffffffffff8082111561215757600080fd5b6121638683870161204b565b9350602085013591508082111561217957600080fd5b50612122858286016120c9565b60006020828403121561219857600080fd5b813565ffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126121e357600080fd5b83018035915067ffffffffffffffff8211156121fe57600080fd5b6020019150600581901b360382131561221657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561225e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122b757600080fd5b83018035915067ffffffffffffffff8211156122d257600080fd5b60200191503681900382131561221657600080fd5b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156123bb57600080fd5b5051919050565b600080604083850312156123d557600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203612446576124466123e6565b5060000390565b60006020828403121561245f57600080fd5b813561ffff811681146104f557600080fd5b80820180821115610249576102496123e6565b61ffff82811682821603908082111561249f5761249f6123e6565b5092915050565b8082028115828204841417610249576102496123e6565b6000826124f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561250a57600080fd5b815180151581146104f557600080fd5b60005b8381101561253557818101518382015260200161251d565b50506000910152565b6000825161255081846020870161251a565b9190910192915050565b602081526000825180602084015261257981604085016020870161251a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122020ef15a82dfe9e15884ad78a08e0e295c6c50a821511c6e99799a1a517eefc3564736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/WarpLink.json b/packages/hardhat/deployments/mainnet/WarpLink.json index 90aa05fc..2fdf3fe1 100644 --- a/packages/hardhat/deployments/mainnet/WarpLink.json +++ b/packages/hardhat/deployments/mainnet/WarpLink.json @@ -1,5 +1,5 @@ { - "address": "0x7F1e509c97be49789aEd68B790D7CEE2D82481a5", + "address": "0x524710A182Ad9cC1042834834ACD0B5070866Db5", "abi": [ { "inputs": [], @@ -249,6 +249,71 @@ "stateMutability": "nonpayable", "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" + } + ], + "name": "warpLinkEngage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -326,34 +391,34 @@ "type": "tuple" } ], - "name": "warpLinkEngage", + "name": "warpLinkEngagePermit", "outputs": [], "stateMutability": "payable", "type": "function" } ], - "transactionHash": "0x1d93891d1e23784f034fdb4fea687307a245e44e89631852d7e1b9cda604e15d", + "transactionHash": "0x3ef5b096fd402423a65a91d5cbbaf87e676ec02d16011b46f348f4a4142a21fb", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x7F1e509c97be49789aEd68B790D7CEE2D82481a5", - "transactionIndex": 161, - "gasUsed": "4673811", + "contractAddress": "0x524710A182Ad9cC1042834834ACD0B5070866Db5", + "transactionIndex": 66, + "gasUsed": "5127020", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x3841880707c408970fa87879686198400abbc7d561c27f50244b711df0fa7dc8", - "transactionHash": "0x1d93891d1e23784f034fdb4fea687307a245e44e89631852d7e1b9cda604e15d", + "blockHash": "0xb2ef4c5d9e632929cde053988dad02c1c0c1f1bc0cf475deedfcec7b466ff569", + "transactionHash": "0x3ef5b096fd402423a65a91d5cbbaf87e676ec02d16011b46f348f4a4142a21fb", "logs": [], - "blockNumber": 18439169, - "cumulativeGasUsed": "15571829", + "blockNumber": 18511200, + "cumulativeGasUsed": "9857549", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 15, - "solcInputHash": "62b3897f582f2743ff2d0ddfebde07d0", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"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\":\"InvalidSgReceiveSrcAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSgReceiverSender\",\"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\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"bytes\",\"name\":\"_srcAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountLD\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sgReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{\"sgReceive(uint16,bytes,uint256,address,uint256,bytes)\":{\"notice\":\"Cross-chain callback from Stargate The tokens have already been received by this contract, `t.payer` is set to this contract before `sgReceive` is called by the router. The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the same message more than once. The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the Stargate composer be compromised, an attacker can drain this contract. If the payload can not be decoded, tokens are left in this contract. If execution runs out of gas, tokens are left in this contract. If an error occurs during engage, such as insufficient output amount, tokens are refunded to the recipient. See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\"}},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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';\\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\\n bytes payload;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n address paramTokenIn;\\n uint256 paramAmountIn;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint48 paramDeadline;\\n uint256 amount;\\n address payer;\\n address token;\\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 useEth: isFromEth || isToEth,\\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 * Cross-chain callback from Stargate\\n *\\n * The tokens have already been received by this contract, `t.payer` is set to this contract\\n * before `sgReceive` is called by the router.\\n *\\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\\n * same message more than once.\\n *\\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\\n * Stargate composer be compromised, an attacker can drain this contract.\\n *\\n * If the payload can not be decoded, tokens are left in this contract.\\n * If execution runs out of gas, tokens are left in this contract.\\n *\\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\\n * to the recipient.\\n *\\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\\n */\\n function sgReceive(\\n uint16, // _srcChainId\\n bytes memory _srcAddress,\\n uint256, // _nonce\\n address _token,\\n uint256 amountLD,\\n bytes memory payload\\n ) external {\\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\\n revert InvalidSgReceiverSender();\\n }\\n\\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\\n // From https://ethereum.stackexchange.com/a/50528\\n address srcAddress;\\n\\n assembly {\\n srcAddress := mload(add(_srcAddress, 20))\\n }\\n\\n if (srcAddress != address(this)) {\\n // NOTE: This assumes that this contract is deployed at the same address on every chain\\n revert InvalidSgReceiveSrcAddress();\\n }\\n\\n Params memory params = abi.decode(payload, (Params));\\n\\n if (params.tokenIn == address(0)) {\\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\\n // otherwise because `_token` may be different on this chain\\n _token = address(0);\\n }\\n\\n try\\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\\n Params({\\n partner: params.partner,\\n feeBps: params.feeBps,\\n slippageBps: params.slippageBps,\\n recipient: params.recipient,\\n tokenIn: _token,\\n tokenOut: params.tokenOut,\\n amountIn: amountLD,\\n amountOut: params.amountOut,\\n deadline: params.deadline,\\n commands: params.commands\\n }),\\n PermitParams({nonce: 0, signature: ''})\\n )\\n {} catch {\\n // Refund tokens to the recipient\\n if (_token == address(0)) {\\n payable(params.recipient).transfer(amountLD);\\n } else {\\n IERC20(_token).safeTransfer(params.recipient, amountLD);\\n }\\n }\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\\n * in this function.\\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 * - dstGasForCall (uint32)\\n * - tokenOut (address) when `dstGasForCall` > 0\\n * - amountOut (uint256) when `dstGasForCall` > 0\\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n params.dstGasForCall = stream.readUint32();\\n\\n if (params.dstGasForCall > 0) {\\n // NOTE: `amountIn` is left as zero\\n Params memory destParams;\\n destParams.partner = t.paramPartner;\\n destParams.feeBps = t.paramFeeBps;\\n destParams.slippageBps = t.paramSlippageBps;\\n destParams.recipient = t.paramRecipient;\\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\\n // the same address as on this chain\\n destParams.tokenIn = t.token;\\n destParams.tokenOut = stream.readAddress();\\n destParams.amountOut = stream.readUint256();\\n destParams.deadline = t.paramDeadline;\\n destParams.commands = stream.readBytes();\\n params.payload = abi.encode(destParams);\\n }\\n\\n if (t.token != t.paramTokenIn) {\\n if (params.payload.length == 0) {\\n // If the tokens are being delivered directly to the recipient without a second\\n // WarpLink engage, the fee is charged on this chain\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibStarVault.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n }\\n\\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\\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. When there is a payload, the composer is used, else the router\\n IERC20(t.token).forceApprove(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\\n t.amount\\n );\\n }\\n\\n t.jumped = 1;\\n\\n // Swap on the composer if there is a payload, else the router\\n IStargateRouter(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\\n ).swap{\\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\\n }({\\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\\n // more on the other chain. It also assumes the tokens are of nearly equal value\\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: params.dstGasForCall,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n // NOTE: This assumes the contract is deployed at the same address on every chain.\\n // If this is not the case, a new param needs to be added with the next WarpLink address\\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\\n _payload: params.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.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\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 // The signature is omitted when `warpLinkEngage` is called from `sgReceive`\\n if (permit.signature.length > 0) {\\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\\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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0x198e2bb767f975464f62ecb8578721d7516f8da1302b3acfd3c622258de1320e\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\\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 error InvalidSgReceiverSender();\\n error InvalidSgReceiveSrcAddress();\\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\":\"0xc1d8b9ba2a1f8300c00adc2c66fd51da23bb40db78ce5b7fe270bb7ee77e923e\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IStargateReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\n\\ninterface IStargateReceiver {\\n function sgReceive(\\n uint16 _srcChainId, // the remote chainId sending the tokens\\n bytes memory _srcAddress, // the remote Bridge address\\n uint256 _nonce,\\n address _token, // the token contract on the local chain\\n uint256 amountLD, // the qty of local _token contract tokens\\n bytes memory payload\\n ) external;\\n}\\n\",\"keccak256\":\"0x7fd06c09139156a4f09a77eac28e453a1d2041a8cf01a108fc875c65192cb637\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50615400806100206000396000f3fe6080604052600436106100295760003560e01c8063ab8236f31461002e578063dc7b39db14610050575b600080fd5b34801561003a57600080fd5b5061004e610049366004614a1e565b610063565b005b61004e61005e366004614af2565b61036f565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff1633146100d6576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461012a576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906101409190614c9f565b608081015190915073ffffffffffffffffffffffffffffffffffffffff1661016757600094505b3063dc7b39db73ffffffffffffffffffffffffffffffffffffffff871615610190576000610192565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff168152602001856101200151815250604051806040016040528060008152602001604051806020016040528060008152508152506040518463ffffffff1660e01b81526004016102a4929190614efc565b6000604051808303818588803b1580156102bd57600080fd5b505af1935050505080156102cf575060015b6103655773ffffffffffffffffffffffffffffffffffffffff851661033e57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610338573d6000803e3d6000fd5b50610365565b60608101516103659073ffffffffffffffffffffffffffffffffffffffff87169086610981565b5050505050505050565b81610100015165ffffffffffff164211156103b6576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015161ffff9081169184019190915260408086018051831660c08087019182526060808a01518716948801949094526080808a01805188169589019590955290890180519188019190915260e0808a015160a0890152925190941690526101008088015165ffffffffffff169186019190915291519184019190915280518216610140840152511661052a578260c00151341015610509576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08301516105189034614f63565b610180820152306101208201526106bd565b336101208201523461018082015260006105476020840184614f76565b905011156106bd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff1681525085806020019061066b9190614f76565b6040518563ffffffff1660e01b815260040161068a9493929190614fe2565b600060405180830381600087803b1580156106a457600080fd5b505af11580156106b8573d6000803e3d6000fd5b505050505b60006106e2846101200151604080518082019091528181528151909101602082015290565b90506106ee8183610a5a565b61010081015161014082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610755576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107678660e001518760400151610c37565b8210156107a0576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361016001516001036107b557505050505050565b6107d686600001518760a00151886020015161ffff168960e0015186610c65565b915081600003610812576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661087d57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610877573d6000803e3d6000fd5b506108a4565b60608601516108a49073ffffffffffffffffffffffffffffffffffffffff83169084610981565b610180840151156108e257610180840151604051339180156108fc02916000818181858888f193505050501580156108e0573d6000803e3d6000fd5b505b8560a0015173ffffffffffffffffffffffffffffffffffffffff16866080015173ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c0015186604051610971929190918252602082015260400190565b60405180910390a4505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610d1e565b505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526000610ad58480516001018051915290565b60ff16905060005b81811015610c2b576000610af78680516001018051915290565b60ff16905060018103610b1457610b0d85610e2d565b9450610c18565b60028103610b2557610b0d85610ff5565b60038103610b3757610b0d8686611254565b60048103610b4957610b0d8686611832565b60058103610b5b57610b0d8686611bb9565b60068103610b6d57610b0d8686612367565b60078103610b7f57610b0d8686612891565b60088103610b9157610b0d8686612dcf565b60098103610be657610ba4600184614f63565b8214610bdc576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d8686613205565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5080610c23816150a4565b915050610add565b50829150505b92915050565b6000612710610c4683826150dc565b610c549061ffff16856150f7565b610c5e919061513d565b9392505050565b60006107d0841115610cac576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610cbe575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610cf45760646032840204610cf7565b60005b9050808303838214610d0f57610d0f8a8a84846139d7565b50505090910395945050505050565b6000610d80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613a9f9092919063ffffffff16565b9050805160001480610da1575080806020019051810190610da19190615178565b610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ca3565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408082018390526101608201839052610180820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610f0a576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014610f5e576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50959695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146110db576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff8116301480159061110957306101208601525b600061014086015280156111bc57600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505050505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916112199160040190815260200190565b600060405180830381600087803b15801561123357600080fd5b505af1158015611247573d6000803e3d6000fd5b5096979650505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff1661130f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff90911603611404576113ff816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b6114e0565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156114c057600080fd5b505af11580156114d4573d6000803e3d6000fd5b50503061012086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161158657905b606083015161010086015161ffff61271092830316918402908202908101908302816115b4576115b461510e565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e9190615208565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161168457876101000151611687565b60005b866040015161169757600061169e565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561170857600080fd5b505af115801561171c573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b49190615208565b9050818110806117d257506101008701516117cf9083615221565b81105b15611809576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915260006118ad8480516001018051915290565b60ff16905060008361010001519050600060028310156118f9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611b84576000611914600188614f63565b82106119205785611951565b6127106119338b80516002018051915290565b61ffff168a610100015161194791906150f7565b611951919061513d565b90508581111561198d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119978187614f63565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261012080820183815261014080840185815261016085018690526101808501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d015116909152909650611a368b82610a5a565b9050806101600151600103611a77576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611a945780610120015193508061014001519450611b68565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614611afe576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614611b68576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100810151611b789087615221565b955050506001016118ff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152611c4660405180606001604052806060815260200160608152602001606081525090565b6000611c588580516001018051915290565b60ff169050611c68816001615221565b67ffffffffffffffff811115611c8057611c806148ad565b604051908082528060200260200182016040528015611ca9578160200160208202803683370190505b508083526101408501518151909190600090611cc757611cc7615234565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b81811015611d6057855160140180519087528351611d23836001615221565b81518110611d3357611d33615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611d04565b50611d6b8582613ab6565b6020830152611d7a8582613b58565b6040830152815180516000919083908110611d9757611d97615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e319190615208565b90506000611e52846040015187610100015186600001518760200151613be1565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff1603611ee457611edf8460200151600081518110611ea657611ea6615234565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b611fe3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c78516929190600090611f4357611f43615234565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b8152600401611fa9949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015611fc357600080fd5b505af1158015611fd7573d6000803e3d6000fd5b50503061012089015250505b60005b838110156121e7576000611ffb826001615221565b905060008660000151828151811061201557612015615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168760000151848151811061204957612049615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612073576000612076565b60015b90506000600288600001515161208c9190614f63565b841061209857306120b7565b876020015183815181106120ae576120ae615234565b60200260200101515b9050876020015184815181106120cf576120cf615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836121165786858151811061210957612109615234565b6020026020010151612119565b60005b84612125576000612140565b87868151811061213757612137615234565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156121c057600080fd5b505af11580156121d4573d6000803e3d6000fd5b505060019095019450611fe69350505050565b5060008460000151848151811061220057612200615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229a9190615208565b905081600183516122ab9190614f63565b815181106122bb576122bb615234565b602002602001015187610100018181525050828110806122e957506101008701516122e69084615221565b81105b15612320576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845180518590811061233457612334615234565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff90811660208301526101408401511661247a576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156124e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250c9190615208565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff161090506125a86040518060600160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff16815250613e16565b801561268c5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561264f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126739190615263565b9150508061268090615287565b61010087015250612774565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561273c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127609190615263565b50905061276c81615287565b610100870152505b61277c613f7f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e9190615208565b90508281108061282c57506101008601516128299084615221565b81105b15612863576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261291e60405180606001604052806060815260200160608152602001606081525090565b60006129308580516001018051915290565b60ff16905061293f8582613ab6565b825261294b8582613ab6565b60208301528151600090612960600184614f63565b8151811061297057612970615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156129eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0f9190615208565b905060005b83811015612cd75760008115612a4e578551612a31600184614f63565b81518110612a4157612a41615234565b6020026020010151612a55565b8761014001515b905085600001518281518110612a6d57612a6d615234565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516060810182526101008d015181526101208d01518416948101949094529184169183018290521190612ace90613e16565b82600003612ade57306101208a01525b600087602001518481518110612af657612af6615234565b602002602001015190508115612be0576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc79190615263565b91505080612bd490615287565b6101008c015250612cc4565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb09190615263565b509050612cbc81615287565b6101008c0152505b612ccc613f7f565b505050600101612a14565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6e9190615208565b905081811080612d8c5750610100870151612d899083615221565b81105b15612dc3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff9283161592918216159130911614613006577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612fe657600080fd5b505af1158015612ffa573d6000803e3d6000fd5b50503061012088015250505b6000816130a35783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561307a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309e9190615208565b6130a5565b475b9050826130e5576130e5846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff16613fdf9092919063ffffffff16565b61312a84608001518560a0015186602001518661310357600061310a565b8961010001515b886040015189606001518c610100015160008b8061312557508a5b6140d5565b6000826131c75784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561319e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c29190615208565b6131c9565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506131f38282614f63565b61010088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526132a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613431576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff166101008201528451602080820180519092010186526101208201526040516133fc9082906020016152bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613543578060800151516000036134a5578251610140840151602085015161010086015161349e93929161ffff169080610c65565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3866080015187610100015160405161353a929190918252602082015260400190565b60405180910390a45b6135558360a001518460c00151610c37565b8361010001511015613593576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff91821691161561377f5761012084015173ffffffffffffffffffffffffffffffffffffffff1630146136d1577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156136b157600080fd5b505af11580156136c5573d6000803e3d6000fd5b50503061012087015250505b61377f8260800151516000146136e75781613756565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613732573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061375691906152d2565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff169190613fdf565b6001610160850152608082015151156137985780613807565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380791906152d2565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff16146138665785610180015161387c565b85610180015186610100015161387c9190615221565b8451602086015160408701516101008a015160c08b01513091906138a1908290610c37565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c6080015151116138e7578d604001516138e9565b305b604051602001613924919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b16835261399499989796959493926004016152ef565b6000604051808303818588803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b5050600061018088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060613aae84846000856145d1565b949350505050565b60608167ffffffffffffffff811115613ad157613ad16148ad565b604051908082528060200260200182016040528015613afa578160200160208202803683370190505b50905060005b82811015613b515783516014018051908552828281518110613b2457613b24615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613b00565b5092915050565b60608167ffffffffffffffff811115613b7357613b736148ad565b604051908082528060200260200182016040528015613b9c578160200160208202803683370190505b50905060005b82811015613b515783516002018051908552828281518110613bc657613bc6615234565b61ffff90921660209283029190910190910152600101613ba2565b805182516060919067ffffffffffffffff811115613c0157613c016148ad565b604051908082528060200260200182016040528015613c2a578160200160208202803683370190505b5091508482600081518110613c4157613c41615234565b60200260200101818152505060005b81811015613e0c576000858281518110613c6c57613c6c615234565b60200260200101519050600086836001613c869190615221565b81518110613c9657613c96615234565b602002602001015190506000898481518110613cb457613cb4615234565b6020026020010151612710613cc991906150dc565b61ffff169050600080888681518110613ce457613ce4615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d5a91906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115613db557905b828b0282612710020181848d020281613dd057613dd061510e565b049a508a88613de0886001615221565b81518110613df057613df0615234565b6020908102919091010152505060019093019250613c50915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613e74576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613fdd576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261406b84826146ea565b6140cf5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526140c59085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109d3565b6140cf8482610d1e565b50505050565b8860ff1660010361420357871561418e576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561417057600080fd5b505af1158015614184573d6000803e3d6000fd5b50505050506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614157565b8860ff166002036143435787156142ce576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156142a3573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906142c89190615208565b506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614285565b8860ff166003036144e45787156143c1576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614285565b801561443b576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614285565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af11580156144c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c89190615208565b8860ff16600403614594578715614527576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614157565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b606082471015614663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ca3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161468c919061539b565b60006040518083038185875af1925050503d80600081146146c9576040519150601f19603f3d011682016040523d82523d6000602084013e6146ce565b606091505b50915091506146df878383876147ab565b979650505050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614714919061539b565b6000604051808303816000865af19150503d8060008114614751576040519150601f19603f3d011682016040523d82523d6000602084013e614756565b606091505b50915091508180156147805750805115806147805750808060200190518101906147809190615178565b80156147a2575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060831561484157825160000361483a5773ffffffffffffffffffffffffffffffffffffffff85163b61483a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca3565b5081613aae565b613aae83838151156148565781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca391906153b7565b61ffff8116811461489a57600080fd5b50565b80356148a88161488a565b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614900576149006148ad565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561494d5761494d6148ad565b604052919050565b600067ffffffffffffffff82111561496f5761496f6148ad565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149ac57600080fd5b81356149bf6149ba82614955565b614906565b8181528460208386010111156149d457600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461489a57600080fd5b80356148a8816149f1565b60008060008060008060c08789031215614a3757600080fd5b8635614a428161488a565b9550602087013567ffffffffffffffff80821115614a5f57600080fd5b614a6b8a838b0161499b565b96506040890135955060608901359150614a84826149f1565b9093506080880135925060a08801359080821115614aa157600080fd5b50614aae89828a0161499b565b9150509295509295509295565b65ffffffffffff8116811461489a57600080fd5b80356148a881614abb565b600060408284031215614aec57600080fd5b50919050565b60008060408385031215614b0557600080fd5b823567ffffffffffffffff80821115614b1d57600080fd5b908401906101408287031215614b3257600080fd5b614b3a6148dc565b614b4383614a13565b8152614b516020840161489d565b6020820152614b626040840161489d565b6040820152614b7360608401614a13565b6060820152614b8460808401614a13565b6080820152614b9560a08401614a13565b60a082015260c083013560c082015260e083013560e0820152610100614bbc818501614acf565b908201526101208381013583811115614bd457600080fd5b614be08982870161499b565b828401525050809450506020850135915080821115614bfe57600080fd5b50614c0b85828601614ada565b9150509250929050565b80516148a8816149f1565b80516148a88161488a565b80516148a881614abb565b60005b83811015614c51578181015183820152602001614c39565b50506000910152565b600082601f830112614c6b57600080fd5b8151614c796149ba82614955565b818152846020838601011115614c8e57600080fd5b613aae826020830160208701614c36565b600060208284031215614cb157600080fd5b815167ffffffffffffffff80821115614cc957600080fd5b908301906101408286031215614cde57600080fd5b614ce66148dc565b614cef83614c15565b8152614cfd60208401614c20565b6020820152614d0e60408401614c20565b6040820152614d1f60608401614c15565b6060820152614d3060808401614c15565b6080820152614d4160a08401614c15565b60a082015260c083015160c082015260e083015160e0820152610100614d68818501614c2b565b908201526101208381015183811115614d8057600080fd5b614d8c88828701614c5a565b918301919091525095945050505050565b60008151808452614db5816020860160208601614c36565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006101406020830151614e1b602086018261ffff169052565b506040830151614e31604086018261ffff169052565b506060830151614e59606086018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151614e81608086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614ea960a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015160c085015260e083015160e085015261010080840151614ed88287018265ffffffffffff169052565b5050610120808401518282870152614ef283870182614d9d565b9695505050505050565b604081526000614f0f6040830185614de7565b828103602084015283518152602084015160406020830152614ef26040830182614d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c3157610c31614f34565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614fab57600080fd5b83018035915067ffffffffffffffff821115614fc657600080fd5b602001915036819003821315614fdb57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150d5576150d5614f34565b5060010190565b61ffff828116828216039080821115613b5157613b51614f34565b8082028115828204841417610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615173577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561518a57600080fd5b81518015158114610c5e57600080fd5b80516dffffffffffffffffffffffffffff811681146148a857600080fd5b6000806000606084860312156151cd57600080fd5b6151d68461519a565b92506151e46020850161519a565b9150604084015163ffffffff811681146151fd57600080fd5b809150509250925092565b60006020828403121561521a57600080fd5b5051919050565b80820180821115610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561527657600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036152b8576152b8614f34565b5060000390565b602081526000610c5e6020830184614de7565b6000602082840312156152e457600080fd5b8151610c5e816149f1565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615362610180840182614d9d565b905082810360e08401526153768186614d9d565b905082810361010084015261538b8185614d9d565b9c9b505050505050505050505050565b600082516153ad818460208701614c36565b9190910192915050565b602081526000610c5e6020830184614d9d56fea26469706673582212204eecdc76d361ea4a608ec1291a66f39b61f591d844e03c8f4164adb5e8c419c464736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c8063ab8236f31461002e578063dc7b39db14610050575b600080fd5b34801561003a57600080fd5b5061004e610049366004614a1e565b610063565b005b61004e61005e366004614af2565b61036f565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff1633146100d6576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461012a576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906101409190614c9f565b608081015190915073ffffffffffffffffffffffffffffffffffffffff1661016757600094505b3063dc7b39db73ffffffffffffffffffffffffffffffffffffffff871615610190576000610192565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff168152602001856101200151815250604051806040016040528060008152602001604051806020016040528060008152508152506040518463ffffffff1660e01b81526004016102a4929190614efc565b6000604051808303818588803b1580156102bd57600080fd5b505af1935050505080156102cf575060015b6103655773ffffffffffffffffffffffffffffffffffffffff851661033e57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610338573d6000803e3d6000fd5b50610365565b60608101516103659073ffffffffffffffffffffffffffffffffffffffff87169086610981565b5050505050505050565b81610100015165ffffffffffff164211156103b6576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015161ffff9081169184019190915260408086018051831660c08087019182526060808a01518716948801949094526080808a01805188169589019590955290890180519188019190915260e0808a015160a0890152925190941690526101008088015165ffffffffffff169186019190915291519184019190915280518216610140840152511661052a578260c00151341015610509576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08301516105189034614f63565b610180820152306101208201526106bd565b336101208201523461018082015260006105476020840184614f76565b905011156106bd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff1681525085806020019061066b9190614f76565b6040518563ffffffff1660e01b815260040161068a9493929190614fe2565b600060405180830381600087803b1580156106a457600080fd5b505af11580156106b8573d6000803e3d6000fd5b505050505b60006106e2846101200151604080518082019091528181528151909101602082015290565b90506106ee8183610a5a565b61010081015161014082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610755576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107678660e001518760400151610c37565b8210156107a0576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361016001516001036107b557505050505050565b6107d686600001518760a00151886020015161ffff168960e0015186610c65565b915081600003610812576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661087d57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610877573d6000803e3d6000fd5b506108a4565b60608601516108a49073ffffffffffffffffffffffffffffffffffffffff83169084610981565b610180840151156108e257610180840151604051339180156108fc02916000818181858888f193505050501580156108e0573d6000803e3d6000fd5b505b8560a0015173ffffffffffffffffffffffffffffffffffffffff16866080015173ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c0015186604051610971929190918252602082015260400190565b60405180910390a4505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610d1e565b505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526000610ad58480516001018051915290565b60ff16905060005b81811015610c2b576000610af78680516001018051915290565b60ff16905060018103610b1457610b0d85610e2d565b9450610c18565b60028103610b2557610b0d85610ff5565b60038103610b3757610b0d8686611254565b60048103610b4957610b0d8686611832565b60058103610b5b57610b0d8686611bb9565b60068103610b6d57610b0d8686612367565b60078103610b7f57610b0d8686612891565b60088103610b9157610b0d8686612dcf565b60098103610be657610ba4600184614f63565b8214610bdc576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d8686613205565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5080610c23816150a4565b915050610add565b50829150505b92915050565b6000612710610c4683826150dc565b610c549061ffff16856150f7565b610c5e919061513d565b9392505050565b60006107d0841115610cac576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610cbe575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610cf45760646032840204610cf7565b60005b9050808303838214610d0f57610d0f8a8a84846139d7565b50505090910395945050505050565b6000610d80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613a9f9092919063ffffffff16565b9050805160001480610da1575080806020019051810190610da19190615178565b610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ca3565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408082018390526101608201839052610180820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610f0a576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014610f5e576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50959695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146110db576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff8116301480159061110957306101208601525b600061014086015280156111bc57600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505050505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916112199160040190815260200190565b600060405180830381600087803b15801561123357600080fd5b505af1158015611247573d6000803e3d6000fd5b5096979650505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff1661130f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff90911603611404576113ff816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b6114e0565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156114c057600080fd5b505af11580156114d4573d6000803e3d6000fd5b50503061012086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161158657905b606083015161010086015161ffff61271092830316918402908202908101908302816115b4576115b461510e565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e9190615208565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161168457876101000151611687565b60005b866040015161169757600061169e565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561170857600080fd5b505af115801561171c573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b49190615208565b9050818110806117d257506101008701516117cf9083615221565b81105b15611809576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915260006118ad8480516001018051915290565b60ff16905060008361010001519050600060028310156118f9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611b84576000611914600188614f63565b82106119205785611951565b6127106119338b80516002018051915290565b61ffff168a610100015161194791906150f7565b611951919061513d565b90508581111561198d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119978187614f63565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261012080820183815261014080840185815261016085018690526101808501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d015116909152909650611a368b82610a5a565b9050806101600151600103611a77576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611a945780610120015193508061014001519450611b68565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614611afe576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614611b68576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100810151611b789087615221565b955050506001016118ff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152611c4660405180606001604052806060815260200160608152602001606081525090565b6000611c588580516001018051915290565b60ff169050611c68816001615221565b67ffffffffffffffff811115611c8057611c806148ad565b604051908082528060200260200182016040528015611ca9578160200160208202803683370190505b508083526101408501518151909190600090611cc757611cc7615234565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b81811015611d6057855160140180519087528351611d23836001615221565b81518110611d3357611d33615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611d04565b50611d6b8582613ab6565b6020830152611d7a8582613b58565b6040830152815180516000919083908110611d9757611d97615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e319190615208565b90506000611e52846040015187610100015186600001518760200151613be1565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff1603611ee457611edf8460200151600081518110611ea657611ea6615234565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b611fe3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c78516929190600090611f4357611f43615234565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b8152600401611fa9949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015611fc357600080fd5b505af1158015611fd7573d6000803e3d6000fd5b50503061012089015250505b60005b838110156121e7576000611ffb826001615221565b905060008660000151828151811061201557612015615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168760000151848151811061204957612049615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612073576000612076565b60015b90506000600288600001515161208c9190614f63565b841061209857306120b7565b876020015183815181106120ae576120ae615234565b60200260200101515b9050876020015184815181106120cf576120cf615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836121165786858151811061210957612109615234565b6020026020010151612119565b60005b84612125576000612140565b87868151811061213757612137615234565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156121c057600080fd5b505af11580156121d4573d6000803e3d6000fd5b505060019095019450611fe69350505050565b5060008460000151848151811061220057612200615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229a9190615208565b905081600183516122ab9190614f63565b815181106122bb576122bb615234565b602002602001015187610100018181525050828110806122e957506101008701516122e69084615221565b81105b15612320576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845180518590811061233457612334615234565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff90811660208301526101408401511661247a576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156124e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250c9190615208565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff161090506125a86040518060600160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff16815250613e16565b801561268c5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561264f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126739190615263565b9150508061268090615287565b61010087015250612774565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561273c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127609190615263565b50905061276c81615287565b610100870152505b61277c613f7f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e9190615208565b90508281108061282c57506101008601516128299084615221565b81105b15612863576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261291e60405180606001604052806060815260200160608152602001606081525090565b60006129308580516001018051915290565b60ff16905061293f8582613ab6565b825261294b8582613ab6565b60208301528151600090612960600184614f63565b8151811061297057612970615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156129eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0f9190615208565b905060005b83811015612cd75760008115612a4e578551612a31600184614f63565b81518110612a4157612a41615234565b6020026020010151612a55565b8761014001515b905085600001518281518110612a6d57612a6d615234565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516060810182526101008d015181526101208d01518416948101949094529184169183018290521190612ace90613e16565b82600003612ade57306101208a01525b600087602001518481518110612af657612af6615234565b602002602001015190508115612be0576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc79190615263565b91505080612bd490615287565b6101008c015250612cc4565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb09190615263565b509050612cbc81615287565b6101008c0152505b612ccc613f7f565b505050600101612a14565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6e9190615208565b905081811080612d8c5750610100870151612d899083615221565b81105b15612dc3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff9283161592918216159130911614613006577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612fe657600080fd5b505af1158015612ffa573d6000803e3d6000fd5b50503061012088015250505b6000816130a35783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561307a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309e9190615208565b6130a5565b475b9050826130e5576130e5846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff16613fdf9092919063ffffffff16565b61312a84608001518560a0015186602001518661310357600061310a565b8961010001515b886040015189606001518c610100015160008b8061312557508a5b6140d5565b6000826131c75784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561319e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c29190615208565b6131c9565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506131f38282614f63565b61010088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526132a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613431576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff166101008201528451602080820180519092010186526101208201526040516133fc9082906020016152bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613543578060800151516000036134a5578251610140840151602085015161010086015161349e93929161ffff169080610c65565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3866080015187610100015160405161353a929190918252602082015260400190565b60405180910390a45b6135558360a001518460c00151610c37565b8361010001511015613593576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff91821691161561377f5761012084015173ffffffffffffffffffffffffffffffffffffffff1630146136d1577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156136b157600080fd5b505af11580156136c5573d6000803e3d6000fd5b50503061012087015250505b61377f8260800151516000146136e75781613756565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613732573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061375691906152d2565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff169190613fdf565b6001610160850152608082015151156137985780613807565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380791906152d2565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff16146138665785610180015161387c565b85610180015186610100015161387c9190615221565b8451602086015160408701516101008a015160c08b01513091906138a1908290610c37565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c6080015151116138e7578d604001516138e9565b305b604051602001613924919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b16835261399499989796959493926004016152ef565b6000604051808303818588803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b5050600061018088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060613aae84846000856145d1565b949350505050565b60608167ffffffffffffffff811115613ad157613ad16148ad565b604051908082528060200260200182016040528015613afa578160200160208202803683370190505b50905060005b82811015613b515783516014018051908552828281518110613b2457613b24615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613b00565b5092915050565b60608167ffffffffffffffff811115613b7357613b736148ad565b604051908082528060200260200182016040528015613b9c578160200160208202803683370190505b50905060005b82811015613b515783516002018051908552828281518110613bc657613bc6615234565b61ffff90921660209283029190910190910152600101613ba2565b805182516060919067ffffffffffffffff811115613c0157613c016148ad565b604051908082528060200260200182016040528015613c2a578160200160208202803683370190505b5091508482600081518110613c4157613c41615234565b60200260200101818152505060005b81811015613e0c576000858281518110613c6c57613c6c615234565b60200260200101519050600086836001613c869190615221565b81518110613c9657613c96615234565b602002602001015190506000898481518110613cb457613cb4615234565b6020026020010151612710613cc991906150dc565b61ffff169050600080888681518110613ce457613ce4615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d5a91906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115613db557905b828b0282612710020181848d020281613dd057613dd061510e565b049a508a88613de0886001615221565b81518110613df057613df0615234565b6020908102919091010152505060019093019250613c50915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613e74576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613fdd576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261406b84826146ea565b6140cf5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526140c59085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109d3565b6140cf8482610d1e565b50505050565b8860ff1660010361420357871561418e576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561417057600080fd5b505af1158015614184573d6000803e3d6000fd5b50505050506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614157565b8860ff166002036143435787156142ce576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156142a3573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906142c89190615208565b506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614285565b8860ff166003036144e45787156143c1576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614285565b801561443b576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614285565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af11580156144c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c89190615208565b8860ff16600403614594578715614527576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614157565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b606082471015614663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ca3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161468c919061539b565b60006040518083038185875af1925050503d80600081146146c9576040519150601f19603f3d011682016040523d82523d6000602084013e6146ce565b606091505b50915091506146df878383876147ab565b979650505050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614714919061539b565b6000604051808303816000865af19150503d8060008114614751576040519150601f19603f3d011682016040523d82523d6000602084013e614756565b606091505b50915091508180156147805750805115806147805750808060200190518101906147809190615178565b80156147a2575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060831561484157825160000361483a5773ffffffffffffffffffffffffffffffffffffffff85163b61483a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca3565b5081613aae565b613aae83838151156148565781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca391906153b7565b61ffff8116811461489a57600080fd5b50565b80356148a88161488a565b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614900576149006148ad565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561494d5761494d6148ad565b604052919050565b600067ffffffffffffffff82111561496f5761496f6148ad565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149ac57600080fd5b81356149bf6149ba82614955565b614906565b8181528460208386010111156149d457600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461489a57600080fd5b80356148a8816149f1565b60008060008060008060c08789031215614a3757600080fd5b8635614a428161488a565b9550602087013567ffffffffffffffff80821115614a5f57600080fd5b614a6b8a838b0161499b565b96506040890135955060608901359150614a84826149f1565b9093506080880135925060a08801359080821115614aa157600080fd5b50614aae89828a0161499b565b9150509295509295509295565b65ffffffffffff8116811461489a57600080fd5b80356148a881614abb565b600060408284031215614aec57600080fd5b50919050565b60008060408385031215614b0557600080fd5b823567ffffffffffffffff80821115614b1d57600080fd5b908401906101408287031215614b3257600080fd5b614b3a6148dc565b614b4383614a13565b8152614b516020840161489d565b6020820152614b626040840161489d565b6040820152614b7360608401614a13565b6060820152614b8460808401614a13565b6080820152614b9560a08401614a13565b60a082015260c083013560c082015260e083013560e0820152610100614bbc818501614acf565b908201526101208381013583811115614bd457600080fd5b614be08982870161499b565b828401525050809450506020850135915080821115614bfe57600080fd5b50614c0b85828601614ada565b9150509250929050565b80516148a8816149f1565b80516148a88161488a565b80516148a881614abb565b60005b83811015614c51578181015183820152602001614c39565b50506000910152565b600082601f830112614c6b57600080fd5b8151614c796149ba82614955565b818152846020838601011115614c8e57600080fd5b613aae826020830160208701614c36565b600060208284031215614cb157600080fd5b815167ffffffffffffffff80821115614cc957600080fd5b908301906101408286031215614cde57600080fd5b614ce66148dc565b614cef83614c15565b8152614cfd60208401614c20565b6020820152614d0e60408401614c20565b6040820152614d1f60608401614c15565b6060820152614d3060808401614c15565b6080820152614d4160a08401614c15565b60a082015260c083015160c082015260e083015160e0820152610100614d68818501614c2b565b908201526101208381015183811115614d8057600080fd5b614d8c88828701614c5a565b918301919091525095945050505050565b60008151808452614db5816020860160208601614c36565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006101406020830151614e1b602086018261ffff169052565b506040830151614e31604086018261ffff169052565b506060830151614e59606086018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151614e81608086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614ea960a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015160c085015260e083015160e085015261010080840151614ed88287018265ffffffffffff169052565b5050610120808401518282870152614ef283870182614d9d565b9695505050505050565b604081526000614f0f6040830185614de7565b828103602084015283518152602084015160406020830152614ef26040830182614d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c3157610c31614f34565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614fab57600080fd5b83018035915067ffffffffffffffff821115614fc657600080fd5b602001915036819003821315614fdb57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150d5576150d5614f34565b5060010190565b61ffff828116828216039080821115613b5157613b51614f34565b8082028115828204841417610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615173577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561518a57600080fd5b81518015158114610c5e57600080fd5b80516dffffffffffffffffffffffffffff811681146148a857600080fd5b6000806000606084860312156151cd57600080fd5b6151d68461519a565b92506151e46020850161519a565b9150604084015163ffffffff811681146151fd57600080fd5b809150509250925092565b60006020828403121561521a57600080fd5b5051919050565b80820180821115610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561527657600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036152b8576152b8614f34565b5060000390565b602081526000610c5e6020830184614de7565b6000602082840312156152e457600080fd5b8151610c5e816149f1565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615362610180840182614d9d565b905082810360e08401526153768186614d9d565b905082810361010084015261538b8185614d9d565b9c9b505050505050505050505050565b600082516153ad818460208701614c36565b9190910192915050565b602081526000610c5e6020830184614d9d56fea26469706673582212204eecdc76d361ea4a608ec1291a66f39b61f591d844e03c8f4164adb5e8c419c464736f6c63430008130033", + "numDeployments": 16, + "solcInputHash": "b02a0ce4f8d2d52325669cdc01d21082", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"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\":\"InvalidSgReceiveSrcAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSgReceiverSender\",\"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\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"bytes\",\"name\":\"_srcAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountLD\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sgReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"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\":\"warpLinkEngagePermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{\"sgReceive(uint16,bytes,uint256,address,uint256,bytes)\":{\"notice\":\"Cross-chain callback from Stargate The tokens have already been received by this contract, `t.payer` is set to this contract before `sgReceive` is called by the router. The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the same message more than once. The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the Stargate composer be compromised, an attacker can drain this contract. If the payload can not be decoded, tokens are left in this contract. If execution runs out of gas, tokens are left in this contract. If an error occurs during engage, such as insufficient output amount, tokens are refunded to the recipient. See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\"}},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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';\\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\\n bytes payload;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n address paramTokenIn;\\n uint256 paramAmountIn;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint48 paramDeadline;\\n uint256 amount;\\n address payer;\\n address token;\\n /**\\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\\n */\\n uint256 usePermit;\\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 if (t.usePermit == 1) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\\n }\\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 if (t.usePermit == 1) {\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\\n }\\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 if (t.usePermit == 1) {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(\\n t.payer,\\n params.pools[0],\\n (uint160)(t.amount),\\n t.token\\n );\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\\n }\\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({\\n payer: t.payer,\\n token: t.token,\\n amount: t.amount,\\n usePermit: t.usePermit\\n })\\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({\\n payer: t.payer,\\n token: tokenIn,\\n amount: t.amount,\\n usePermit: t.usePermit\\n })\\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 if (t.usePermit == 1) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\\n }\\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 useEth: isFromEth || isToEth,\\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 * Cross-chain callback from Stargate\\n *\\n * The tokens have already been received by this contract, `t.payer` is set to this contract\\n * before `sgReceive` is called by the router.\\n *\\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\\n * same message more than once.\\n *\\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\\n * Stargate composer be compromised, an attacker can drain this contract.\\n *\\n * If the payload can not be decoded, tokens are left in this contract.\\n * If execution runs out of gas, tokens are left in this contract.\\n *\\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\\n * to the recipient.\\n *\\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\\n */\\n function sgReceive(\\n uint16, // _srcChainId\\n bytes memory _srcAddress,\\n uint256, // _nonce\\n address _token,\\n uint256 amountLD,\\n bytes memory payload\\n ) external {\\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\\n revert InvalidSgReceiverSender();\\n }\\n\\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\\n // From https://ethereum.stackexchange.com/a/50528\\n address srcAddress;\\n\\n assembly {\\n srcAddress := mload(add(_srcAddress, 20))\\n }\\n\\n if (srcAddress != address(this)) {\\n // NOTE: This assumes that this contract is deployed at the same address on every chain\\n revert InvalidSgReceiveSrcAddress();\\n }\\n\\n Params memory params = abi.decode(payload, (Params));\\n\\n if (params.tokenIn == address(0)) {\\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\\n // otherwise because `_token` may be different on this chain\\n _token = address(0);\\n }\\n\\n try\\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\\n Params({\\n partner: params.partner,\\n feeBps: params.feeBps,\\n slippageBps: params.slippageBps,\\n recipient: params.recipient,\\n tokenIn: _token,\\n tokenOut: params.tokenOut,\\n amountIn: amountLD,\\n amountOut: params.amountOut,\\n deadline: params.deadline,\\n commands: params.commands\\n })\\n )\\n {} catch {\\n // Refund tokens to the recipient\\n if (_token == address(0)) {\\n payable(params.recipient).transfer(amountLD);\\n } else {\\n IERC20(_token).safeTransfer(params.recipient, amountLD);\\n }\\n }\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\\n * in this function.\\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 * - dstGasForCall (uint32)\\n * - tokenOut (address) when `dstGasForCall` > 0\\n * - amountOut (uint256) when `dstGasForCall` > 0\\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n params.dstGasForCall = stream.readUint32();\\n\\n if (params.dstGasForCall > 0) {\\n // NOTE: `amountIn` is left as zero\\n Params memory destParams;\\n destParams.partner = t.paramPartner;\\n destParams.feeBps = t.paramFeeBps;\\n destParams.slippageBps = t.paramSlippageBps;\\n destParams.recipient = t.paramRecipient;\\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\\n // the same address as on this chain\\n destParams.tokenIn = t.token;\\n destParams.tokenOut = stream.readAddress();\\n destParams.amountOut = stream.readUint256();\\n destParams.deadline = t.paramDeadline;\\n destParams.commands = stream.readBytes();\\n params.payload = abi.encode(destParams);\\n }\\n\\n if (t.token != t.paramTokenIn) {\\n if (params.payload.length == 0) {\\n // If the tokens are being delivered directly to the recipient without a second\\n // WarpLink engage, the fee is charged on this chain\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibStarVault.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n }\\n\\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\\n\\n if (t.token != address(0)) {\\n if (t.payer != address(this)) {\\n if (t.usePermit == 1) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n t.payer,\\n address(this),\\n (uint160)(t.amount),\\n t.token\\n );\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\\n }\\n\\n // Update the payer to this contract\\n // TODO: Is this value ever read?\\n t.payer = address(this);\\n }\\n\\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\\n IERC20(t.token).forceApprove(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\\n t.amount\\n );\\n }\\n\\n t.jumped = 1;\\n\\n // Swap on the composer if there is a payload, else the router\\n IStargateRouter(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\\n ).swap{\\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\\n }({\\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\\n // more on the other chain. It also assumes the tokens are of nearly equal value\\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: params.dstGasForCall,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n // NOTE: This assumes the contract is deployed at the same address on every chain.\\n // If this is not the case, a new param needs to be added with the next WarpLink address\\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\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\\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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function warpLinkEngagePermit(\\n Params calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n TransientState memory t;\\n t.paramPartner = params.partner;\\n t.paramFeeBps = params.feeBps;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.usePermit = 1;\\n\\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 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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0xafd9df86ea5bc03ea83d33890bbbe7e383f84bec96e5b67dd99e7d717bc9bcb3\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\\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 error InvalidSgReceiverSender();\\n error InvalidSgReceiveSrcAddress();\\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 calldata params) external payable;\\n\\n function warpLinkEngagePermit(\\n Params calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n}\\n\",\"keccak256\":\"0x0eff4788d9f45d72b6a05f34f1e8236a6f9d76a4778396d9a53c66ec04ebf726\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IStargateReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\n\\ninterface IStargateReceiver {\\n function sgReceive(\\n uint16 _srcChainId, // the remote chainId sending the tokens\\n bytes memory _srcAddress, // the remote Bridge address\\n uint256 _nonce,\\n address _token, // the token contract on the local chain\\n uint256 amountLD, // the qty of local _token contract tokens\\n bytes memory payload\\n ) external;\\n}\\n\",\"keccak256\":\"0x7fd06c09139156a4f09a77eac28e453a1d2041a8cf01a108fc875c65192cb637\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50615c3880620000216000396000f3fe6080604052600436106100345760003560e01c8063a703fc4014610039578063ab8236f31461004e578063dcc455511461006e575b600080fd5b61004c610047366004615184565b610081565b005b34801561005a57600080fd5b5061004c610069366004615368565b6106c6565b61004c61007c366004615405565b6109ac565b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152906100fd9084018461543a565b73ffffffffffffffffffffffffffffffffffffffff1681526101256040840160208501615457565b61ffff16602082015261013e6060840160408501615457565b61ffff1660c0820152610157608084016060850161543a565b73ffffffffffffffffffffffffffffffffffffffff16604082015261018260a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0840135608083015260e084013560a08301526101c490840160408501615457565b61ffff1660c08201526101df61012084016101008501615488565b65ffffffffffff1660e082015260c083013561010082015261020760a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff9081166101408301526001610160830152336101208301819052346101a08401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e08101909152921691632b67b570919080606081018061028a60a08b0160808c0161543a565b73ffffffffffffffffffffffffffffffffffffffff908116825260c08b01351660208201526040016102c46101208b016101008c01615488565b65ffffffffffff908116825289351660209182015290825230908201526040016102f661012089016101008a01615488565b65ffffffffffff16905261030d60208701876154a5565b6040518563ffffffff1660e01b815260040161032c9493929190615511565b600060405180830381600087803b15801561034657600080fd5b505af115801561035a573d6000803e3d6000fd5b5050505060006103ae8480610120019061037491906154a5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f4192505050565b90506103ba8183610f5b565b610100810151610140820151919350906103da60c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043e576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61045b60e08701356104566060890160408a01615457565b611140565b821015610494576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361018001516001036104a957505050505050565b6104e86104b9602088018861543a565b6104c960c0890160a08a0161543a565b6104d960408a0160208b01615457565b61ffff168960e001358661116e565b915081600003610524576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661059a5761054f608087016060880161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610594573d6000803e3d6000fd5b506105cb565b6105cb6105ad608088016060890161543a565b73ffffffffffffffffffffffffffffffffffffffff83169084611227565b6101a084015115610609576101a0840151604051339180156108fc02916000818181858888f19350505050158015610607573d6000803e3d6000fd5b505b61061960c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff1661063f60a088016080890161543a565b73ffffffffffffffffffffffffffffffffffffffff16610662602089018961543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c00135866040516106b6929190918252602082015260400190565b60405180910390a4505050505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461078d576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906107a39190615662565b608081015190915073ffffffffffffffffffffffffffffffffffffffff166107ca57600094505b3063dcc4555173ffffffffffffffffffffffffffffffffffffffff8716156107f35760006107f5565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff1681526020018561012001518152506040518363ffffffff1660e01b81526004016108e191906157aa565b6000604051808303818588803b1580156108fa57600080fd5b505af19350505050801561090c575060015b6109a25773ffffffffffffffffffffffffffffffffffffffff851661097b57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610975573d6000803e3d6000fd5b506109a2565b60608101516109a29073ffffffffffffffffffffffffffffffffffffffff87169086611227565b5050505050505050565b6109be61012082016101008301615488565b65ffffffffffff164211156109ff576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082015290610a7b9083018361543a565b73ffffffffffffffffffffffffffffffffffffffff168152610aa36040830160208401615457565b61ffff166020820152610abc6060830160408401615457565b61ffff1660c0820152610ad5608083016060840161543a565b73ffffffffffffffffffffffffffffffffffffffff166040820152610b0060a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0830135608083015260e083013560a0830152610b4290830160408401615457565b61ffff1660c0820152610b5d61012083016101008401615488565b65ffffffffffff1660e082015260c0820135610100820152610b8560a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff166101408201526000610bb360a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1603610c2c578160c00135341015610c0c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c1a60c0830135346158dc565b6101a082015230610120820152610c3b565b33610120820152346101a08201525b6000610c4e6103746101208501856154a5565b9050610c5a8183610f5b565b61010081015161014082015191935090610c7a60c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cde576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cf660e08601356104566060880160408901615457565b821015610d2f576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836101800151600103610d43575050505050565b610d82610d53602087018761543a565b610d6360c0880160a0890161543a565b610d736040890160208a01615457565b61ffff168860e001358661116e565b915081600003610dbe576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e3457610de9608086016060870161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610e2e573d6000803e3d6000fd5b50610e47565b610e476105ad608087016060880161543a565b6101a084015115610e85576101a0840151604051339180156108fc02916000818181858888f19350505050158015610e83573d6000803e3d6000fd5b505b610e9560c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ebb60a087016080880161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ede602088018861543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38860c0013586604051610f32929190918252602082015260400190565b60405180910390a45050505050565b604080518082019091528181528151909101602082015290565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000610fde8480516001018051915290565b60ff16905060005b818110156111345760006110008680516001018051915290565b60ff1690506001810361101d5761101685611300565b9450611121565b6002810361102e57611016856114d0565b600381036110405761101686866117f2565b60048103611052576110168686611e2a565b600581036110645761101686866121c1565b600681036110765761101686866129e3565b60078103611088576110168686612f20565b6008810361109a576110168686613471565b600981036110ef576110ad6001846158dc565b82146110e5576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61101686866138fd565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061112c816158ef565b915050610fe6565b50829150505b92915050565b600061271061114f8382615927565b61115d9061ffff1685615942565b6111679190615988565b9392505050565b60006107d08411156111b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156111c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156111fd5760646032840204611200565b60005b9050808303838214611218576112188a8a8484614125565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112fb9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526141ed565b505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140808201839052610160820183905261018082018390526101a0820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff16156113e5576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014611439576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b1580156114b057600080fd5b505af11580156114c4573d6000803e3d6000fd5b50959695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146115be576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff811630148015906115ec57306101208601525b6000610140860152801561175a578461016001516001036116b057600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b5050505061175a565b82546101008601516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015611734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175891906159c3565b505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916117b79160040190815260200190565b600060405180830381600087803b1580156117d157600080fd5b505af11580156117e5573d6000803e3d6000fd5b5096979650505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff166118b5576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff909116036119aa576119a5816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b611ad8565b826101600151600103611a90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015611a7357600080fd5b505af1158015611a87573d6000803e3d6000fd5b50505050611ad0565b611ad0836101200151826020015185610100015186610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208401525b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151611b7e57905b606083015161010086015161ffff6127109283031691840290820290810190830281611bac57611bac615959565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c469190615a53565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8560400151611c7c57876101000151611c7f565b60005b8660400151611c8f576000611c96565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015611d0057600080fd5b505af1158015611d14573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190615a53565b905081811080611dca5750610100870151611dc79083615a6c565b81105b15611e01576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000611ead8480516001018051915290565b60ff1690506000836101000151905060006002831015611ef9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561218c576000611f146001886158dc565b8210611f205785611f51565b612710611f338b80516002018051915290565b61ffff168a6101000151611f479190615942565b611f519190615988565b905085811115611f8d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f9781876158dc565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610120808201838152610140808401858152610160850186905261018085018690526101a08501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d01511690915290965061203e8b82610f5b565b905080610180015160010361207f576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361209c5780610120015193508061014001519450612170565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614612106576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614612170576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008101516121809087615a6c565b95505050600101611eff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261225660405180606001604052806060815260200160608152602001606081525090565b60006122688580516001018051915290565b60ff169050612278816001615a6c565b67ffffffffffffffff81111561229057612290615202565b6040519080825280602002602001820160405280156122b9578160200160208202803683370190505b5080835261014085015181519091906000906122d7576122d7615a7f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561237057855160140180519087528351612333836001615a6c565b8151811061234357612343615a7f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612314565b5061237b8582614360565b602083015261238a8582614402565b60408301528151805160009190839081106123a7576123a7615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615a53565b9050600061246284604001518761010001518660000151876020015161448b565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff16036124f4576124ef84602001516000815181106124b6576124b6615a7f565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b61265f565b8561016001516001036125fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061256057612560615a7f565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b81526004016125c6949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b50505050612657565b612657866101200151856020015160008151811061261d5761261d615a7f565b602002602001015188610100015189610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208701525b60005b83811015612863576000612677826001615a6c565b905060008660000151828151811061269157612691615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16876000015184815181106126c5576126c5615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106126ef5760006126f2565b60015b90506000600288600001515161270891906158dc565b84106127145730612733565b8760200151838151811061272a5761272a615a7f565b60200260200101515b90508760200151848151811061274b5761274b615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836127925786858151811061278557612785615a7f565b6020026020010151612795565b60005b846127a15760006127bc565b8786815181106127b3576127b3615a7f565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561283c57600080fd5b505af1158015612850573d6000803e3d6000fd5b5050600190950194506126629350505050565b5060008460000151848151811061287c5761287c615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129169190615a53565b9050816001835161292791906158dc565b8151811061293757612937615a7f565b6020026020010151876101000181815250508281108061296557506101008701516129629084615a6c565b81105b1561299c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518051859081106129b0576129b0615a7f565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015261014084015116612afe576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190615a53565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff16109050612c376040518060800160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018761016001518152506146c0565b8015612d1b5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d029190615aae565b91505080612d0f90615ad2565b61010087015250612e03565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def9190615aae565b509050612dfb81615ad2565b610100870152505b612e0b61484f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615a53565b905082811080612ebb5750610100860151612eb89084615a6c565b81105b15612ef2576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a0810191909152612fb560405180606001604052806060815260200160608152602001606081525090565b6000612fc78580516001018051915290565b60ff169050612fd68582614360565b8252612fe28582614360565b60208301528151600090612ff76001846158dc565b8151811061300757613007615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190615a53565b905060005b8381101561337957600081156130e55785516130c86001846158dc565b815181106130d8576130d8615a7f565b60200260200101516130ec565b8761014001515b90508560000151828151811061310457613104615a7f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516080810182526101008d015181526101208d01518416948101949094529184169183018290526101608b015160608401521190613170906146c0565b8260000361318057306101208a01525b60008760200151848151811061319857613198615a7f565b602002602001015190508115613282576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615aae565b9150508061327690615ad2565b6101008c015250613366565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561332e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133529190615aae565b50905061335e81615ad2565b6101008c0152505b61336e61484f565b5050506001016130ab565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156133ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134109190615a53565b90508181108061342e575061010087015161342b9083615a6c565b81105b15613465576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146136fe578461016001516001036136ba577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561369d57600080fd5b505af11580156136b1573d6000803e3d6000fd5b505050506136f6565b6136f68561012001513087610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208601525b60008161379b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137969190615a53565b61379d565b475b9050826137dd576137dd846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166148af9092919063ffffffff16565b61382284608001518560a001518660200151866137fb576000613802565b8961010001515b886040015189606001518c610100015160008b8061381d57508a5b61499f565b6000826138bf5784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ba9190615a53565b6138c1565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506138eb82826158dc565b61010088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526139a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613b31576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff16610100820152845160208082018051909201018652610120820152604051613afc9082906020016157aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613c4357806080015151600003613ba55782516101408401516020850151610100860151613b9e93929161ffff16908061116e565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38660800151876101000151604051613c3a929190918252602082015260400190565b60405180910390a45b613c558360a001518460c00151611140565b8361010001511015613c93576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff918216911615613ecd5761012084015173ffffffffffffffffffffffffffffffffffffffff163014613e1f57836101600151600103613ddb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015613dbe57600080fd5b505af1158015613dd2573d6000803e3d6000fd5b50505050613e17565b613e178461012001513086610100015187610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208501525b613ecd826080015151600014613e355781613ea4565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea49190615b0a565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff1691906148af565b600161018085015260808201515115613ee65780613f55565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f559190615b0a565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff1614613fb457856101a00151613fca565b856101a00151866101000151613fca9190615a6c565b8451602086015160408701516101008a015160c08b0151309190613fef908290611140565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c608001515111614035578d60400151614037565b305b604051602001614072919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b1683526140e29998979695949392600401615b27565b6000604051808303818588803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b505060006101a088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b600061424f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614e9b9092919063ffffffff16565b905080516000148061427057508080602001905181019061427091906159c3565b6112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016111ac565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261435a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611279565b50505050565b60608167ffffffffffffffff81111561437b5761437b615202565b6040519080825280602002602001820160405280156143a4578160200160208202803683370190505b50905060005b828110156143fb57835160140180519085528282815181106143ce576143ce615a7f565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016143aa565b5092915050565b60608167ffffffffffffffff81111561441d5761441d615202565b604051908082528060200260200182016040528015614446578160200160208202803683370190505b50905060005b828110156143fb578351600201805190855282828151811061447057614470615a7f565b61ffff9092166020928302919091019091015260010161444c565b805182516060919067ffffffffffffffff8111156144ab576144ab615202565b6040519080825280602002602001820160405280156144d4578160200160208202803683370190505b50915084826000815181106144eb576144eb615a7f565b60200260200101818152505060005b818110156146b657600085828151811061451657614516615a7f565b602002602001015190506000868360016145309190615a6c565b8151811061454057614540615a7f565b60200260200101519050600089848151811061455e5761455e615a7f565b60200260200101516127106145739190615927565b61ffff16905060008088868151811061458e5761458e615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156145e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146049190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561465f57905b828b0282612710020181848d02028161467a5761467a615959565b049a508a8861468a886001615a6c565b8151811061469a5761469a615a7f565b60209081029190910101525050600190930192506144fa915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361471e576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036148ad576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261493b8482614eb2565b61435a5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526149959085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611279565b61435a84826141ed565b8860ff16600103614acd578715614a58576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015614a3a57600080fd5b505af1158015614a4e573d6000803e3d6000fd5b5050505050614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614a21565b8860ff16600203614c0d578715614b98576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015614b6d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190614b929190615a53565b50614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614b4f565b8860ff16600303614dae578715614c8b576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614b4f565b8015614d05576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614b4f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015614d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b929190615a53565b8860ff16600403614e5e578715614df1576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614a21565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6060614eaa8484600085614f73565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614edc9190615bd3565b6000604051808303816000865af19150503d8060008114614f19576040519150601f19603f3d011682016040523d82523d6000602084013e614f1e565b606091505b5091509150818015614f48575080511580614f48575080806020019051810190614f4891906159c3565b8015614f6a575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b606082471015615005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016111ac565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161502e9190615bd3565b60006040518083038185875af1925050503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b50915091506150818783838761508c565b979650505050505050565b6060831561512257825160000361511b5773ffffffffffffffffffffffffffffffffffffffff85163b61511b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016111ac565b5081614eaa565b614eaa83838151156151375781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac9190615bef565b6000610140828403121561517e57600080fd5b50919050565b6000806040838503121561519757600080fd5b823567ffffffffffffffff808211156151af57600080fd5b6151bb8683870161516b565b935060208501359150808211156151d157600080fd5b508301604081860312156151e457600080fd5b809150509250929050565b61ffff811681146151ff57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561525557615255615202565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156152a2576152a2615202565b604052919050565b600067ffffffffffffffff8211156152c4576152c4615202565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261530157600080fd5b813561531461530f826152aa565b61525b565b81815284602083860101111561532957600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146151ff57600080fd5b60008060008060008060c0878903121561538157600080fd5b863561538c816151ef565b9550602087013567ffffffffffffffff808211156153a957600080fd5b6153b58a838b016152f0565b965060408901359550606089013591506153ce82615346565b9093506080880135925060a088013590808211156153eb57600080fd5b506153f889828a016152f0565b9150509295509295509295565b60006020828403121561541757600080fd5b813567ffffffffffffffff81111561542e57600080fd5b614eaa8482850161516b565b60006020828403121561544c57600080fd5b813561116781615346565b60006020828403121561546957600080fd5b8135611167816151ef565b65ffffffffffff811681146151ff57600080fd5b60006020828403121561549a57600080fd5b813561116781615474565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154da57600080fd5b83018035915067ffffffffffffffff8211156154f557600080fd5b60200191503681900382131561550a57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b80516155de81615346565b919050565b80516155de816151ef565b80516155de81615474565b60005b838110156156145781810151838201526020016155fc565b50506000910152565b600082601f83011261562e57600080fd5b815161563c61530f826152aa565b81815284602083860101111561565157600080fd5b614eaa8260208301602087016155f9565b60006020828403121561567457600080fd5b815167ffffffffffffffff8082111561568c57600080fd5b9083019061014082860312156156a157600080fd5b6156a9615231565b6156b2836155d3565b81526156c0602084016155e3565b60208201526156d1604084016155e3565b60408201526156e2606084016155d3565b60608201526156f3608084016155d3565b608082015261570460a084016155d3565b60a082015260c083015160c082015260e083015160e082015261010061572b8185016155ee565b90820152610120838101518381111561574357600080fd5b61574f8882870161561d565b918301919091525095945050505050565b600081518084526157788160208601602086016155f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526157d160208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516157e8604084018261ffff169052565b50604083015161ffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c083015160e083015260e08301516101008181850152808501519150506101206158938185018365ffffffffffff169052565b840151610140848101529050614eaa610160840182615760565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561113a5761113a6158ad565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615920576159206158ad565b5060010190565b61ffff8281168282160390808211156143fb576143fb6158ad565b808202811582820484141761113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156159d557600080fd5b8151801515811461116757600080fd5b80516dffffffffffffffffffffffffffff811681146155de57600080fd5b600080600060608486031215615a1857600080fd5b615a21846159e5565b9250615a2f602085016159e5565b9150604084015163ffffffff81168114615a4857600080fd5b809150509250925092565b600060208284031215615a6557600080fd5b5051919050565b8082018082111561113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215615ac157600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b0357615b036158ad565b5060000390565b600060208284031215615b1c57600080fd5b815161116781615346565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615b9a610180840182615760565b905082810360e0840152615bae8186615760565b9050828103610100840152615bc38185615760565b9c9b505050505050505050505050565b60008251615be58184602087016155f9565b9190910192915050565b602081526000611167602083018461576056fea26469706673582212202ce6a8f21a153c83c150806f9ce2e260656621d27c2de20b34fdaa1dbce5be3f64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c8063a703fc4014610039578063ab8236f31461004e578063dcc455511461006e575b600080fd5b61004c610047366004615184565b610081565b005b34801561005a57600080fd5b5061004c610069366004615368565b6106c6565b61004c61007c366004615405565b6109ac565b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152906100fd9084018461543a565b73ffffffffffffffffffffffffffffffffffffffff1681526101256040840160208501615457565b61ffff16602082015261013e6060840160408501615457565b61ffff1660c0820152610157608084016060850161543a565b73ffffffffffffffffffffffffffffffffffffffff16604082015261018260a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0840135608083015260e084013560a08301526101c490840160408501615457565b61ffff1660c08201526101df61012084016101008501615488565b65ffffffffffff1660e082015260c083013561010082015261020760a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff9081166101408301526001610160830152336101208301819052346101a08401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e08101909152921691632b67b570919080606081018061028a60a08b0160808c0161543a565b73ffffffffffffffffffffffffffffffffffffffff908116825260c08b01351660208201526040016102c46101208b016101008c01615488565b65ffffffffffff908116825289351660209182015290825230908201526040016102f661012089016101008a01615488565b65ffffffffffff16905261030d60208701876154a5565b6040518563ffffffff1660e01b815260040161032c9493929190615511565b600060405180830381600087803b15801561034657600080fd5b505af115801561035a573d6000803e3d6000fd5b5050505060006103ae8480610120019061037491906154a5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f4192505050565b90506103ba8183610f5b565b610100810151610140820151919350906103da60c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043e576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61045b60e08701356104566060890160408a01615457565b611140565b821015610494576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361018001516001036104a957505050505050565b6104e86104b9602088018861543a565b6104c960c0890160a08a0161543a565b6104d960408a0160208b01615457565b61ffff168960e001358661116e565b915081600003610524576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661059a5761054f608087016060880161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610594573d6000803e3d6000fd5b506105cb565b6105cb6105ad608088016060890161543a565b73ffffffffffffffffffffffffffffffffffffffff83169084611227565b6101a084015115610609576101a0840151604051339180156108fc02916000818181858888f19350505050158015610607573d6000803e3d6000fd5b505b61061960c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff1661063f60a088016080890161543a565b73ffffffffffffffffffffffffffffffffffffffff16610662602089018961543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c00135866040516106b6929190918252602082015260400190565b60405180910390a4505050505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461078d576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906107a39190615662565b608081015190915073ffffffffffffffffffffffffffffffffffffffff166107ca57600094505b3063dcc4555173ffffffffffffffffffffffffffffffffffffffff8716156107f35760006107f5565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff1681526020018561012001518152506040518363ffffffff1660e01b81526004016108e191906157aa565b6000604051808303818588803b1580156108fa57600080fd5b505af19350505050801561090c575060015b6109a25773ffffffffffffffffffffffffffffffffffffffff851661097b57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610975573d6000803e3d6000fd5b506109a2565b60608101516109a29073ffffffffffffffffffffffffffffffffffffffff87169086611227565b5050505050505050565b6109be61012082016101008301615488565b65ffffffffffff164211156109ff576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082015290610a7b9083018361543a565b73ffffffffffffffffffffffffffffffffffffffff168152610aa36040830160208401615457565b61ffff166020820152610abc6060830160408401615457565b61ffff1660c0820152610ad5608083016060840161543a565b73ffffffffffffffffffffffffffffffffffffffff166040820152610b0060a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0830135608083015260e083013560a0830152610b4290830160408401615457565b61ffff1660c0820152610b5d61012083016101008401615488565b65ffffffffffff1660e082015260c0820135610100820152610b8560a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff166101408201526000610bb360a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1603610c2c578160c00135341015610c0c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c1a60c0830135346158dc565b6101a082015230610120820152610c3b565b33610120820152346101a08201525b6000610c4e6103746101208501856154a5565b9050610c5a8183610f5b565b61010081015161014082015191935090610c7a60c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cde576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cf660e08601356104566060880160408901615457565b821015610d2f576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836101800151600103610d43575050505050565b610d82610d53602087018761543a565b610d6360c0880160a0890161543a565b610d736040890160208a01615457565b61ffff168860e001358661116e565b915081600003610dbe576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e3457610de9608086016060870161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610e2e573d6000803e3d6000fd5b50610e47565b610e476105ad608087016060880161543a565b6101a084015115610e85576101a0840151604051339180156108fc02916000818181858888f19350505050158015610e83573d6000803e3d6000fd5b505b610e9560c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ebb60a087016080880161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ede602088018861543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38860c0013586604051610f32929190918252602082015260400190565b60405180910390a45050505050565b604080518082019091528181528151909101602082015290565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000610fde8480516001018051915290565b60ff16905060005b818110156111345760006110008680516001018051915290565b60ff1690506001810361101d5761101685611300565b9450611121565b6002810361102e57611016856114d0565b600381036110405761101686866117f2565b60048103611052576110168686611e2a565b600581036110645761101686866121c1565b600681036110765761101686866129e3565b60078103611088576110168686612f20565b6008810361109a576110168686613471565b600981036110ef576110ad6001846158dc565b82146110e5576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61101686866138fd565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061112c816158ef565b915050610fe6565b50829150505b92915050565b600061271061114f8382615927565b61115d9061ffff1685615942565b6111679190615988565b9392505050565b60006107d08411156111b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156111c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156111fd5760646032840204611200565b60005b9050808303838214611218576112188a8a8484614125565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112fb9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526141ed565b505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140808201839052610160820183905261018082018390526101a0820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff16156113e5576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014611439576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b1580156114b057600080fd5b505af11580156114c4573d6000803e3d6000fd5b50959695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146115be576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff811630148015906115ec57306101208601525b6000610140860152801561175a578461016001516001036116b057600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b5050505061175a565b82546101008601516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015611734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175891906159c3565b505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916117b79160040190815260200190565b600060405180830381600087803b1580156117d157600080fd5b505af11580156117e5573d6000803e3d6000fd5b5096979650505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff166118b5576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff909116036119aa576119a5816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b611ad8565b826101600151600103611a90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015611a7357600080fd5b505af1158015611a87573d6000803e3d6000fd5b50505050611ad0565b611ad0836101200151826020015185610100015186610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208401525b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151611b7e57905b606083015161010086015161ffff6127109283031691840290820290810190830281611bac57611bac615959565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c469190615a53565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8560400151611c7c57876101000151611c7f565b60005b8660400151611c8f576000611c96565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015611d0057600080fd5b505af1158015611d14573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190615a53565b905081811080611dca5750610100870151611dc79083615a6c565b81105b15611e01576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000611ead8480516001018051915290565b60ff1690506000836101000151905060006002831015611ef9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561218c576000611f146001886158dc565b8210611f205785611f51565b612710611f338b80516002018051915290565b61ffff168a6101000151611f479190615942565b611f519190615988565b905085811115611f8d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f9781876158dc565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610120808201838152610140808401858152610160850186905261018085018690526101a08501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d01511690915290965061203e8b82610f5b565b905080610180015160010361207f576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361209c5780610120015193508061014001519450612170565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614612106576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614612170576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008101516121809087615a6c565b95505050600101611eff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261225660405180606001604052806060815260200160608152602001606081525090565b60006122688580516001018051915290565b60ff169050612278816001615a6c565b67ffffffffffffffff81111561229057612290615202565b6040519080825280602002602001820160405280156122b9578160200160208202803683370190505b5080835261014085015181519091906000906122d7576122d7615a7f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561237057855160140180519087528351612333836001615a6c565b8151811061234357612343615a7f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612314565b5061237b8582614360565b602083015261238a8582614402565b60408301528151805160009190839081106123a7576123a7615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615a53565b9050600061246284604001518761010001518660000151876020015161448b565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff16036124f4576124ef84602001516000815181106124b6576124b6615a7f565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b61265f565b8561016001516001036125fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061256057612560615a7f565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b81526004016125c6949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b50505050612657565b612657866101200151856020015160008151811061261d5761261d615a7f565b602002602001015188610100015189610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208701525b60005b83811015612863576000612677826001615a6c565b905060008660000151828151811061269157612691615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16876000015184815181106126c5576126c5615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106126ef5760006126f2565b60015b90506000600288600001515161270891906158dc565b84106127145730612733565b8760200151838151811061272a5761272a615a7f565b60200260200101515b90508760200151848151811061274b5761274b615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836127925786858151811061278557612785615a7f565b6020026020010151612795565b60005b846127a15760006127bc565b8786815181106127b3576127b3615a7f565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561283c57600080fd5b505af1158015612850573d6000803e3d6000fd5b5050600190950194506126629350505050565b5060008460000151848151811061287c5761287c615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129169190615a53565b9050816001835161292791906158dc565b8151811061293757612937615a7f565b6020026020010151876101000181815250508281108061296557506101008701516129629084615a6c565b81105b1561299c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518051859081106129b0576129b0615a7f565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015261014084015116612afe576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190615a53565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff16109050612c376040518060800160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018761016001518152506146c0565b8015612d1b5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d029190615aae565b91505080612d0f90615ad2565b61010087015250612e03565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def9190615aae565b509050612dfb81615ad2565b610100870152505b612e0b61484f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615a53565b905082811080612ebb5750610100860151612eb89084615a6c565b81105b15612ef2576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a0810191909152612fb560405180606001604052806060815260200160608152602001606081525090565b6000612fc78580516001018051915290565b60ff169050612fd68582614360565b8252612fe28582614360565b60208301528151600090612ff76001846158dc565b8151811061300757613007615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190615a53565b905060005b8381101561337957600081156130e55785516130c86001846158dc565b815181106130d8576130d8615a7f565b60200260200101516130ec565b8761014001515b90508560000151828151811061310457613104615a7f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516080810182526101008d015181526101208d01518416948101949094529184169183018290526101608b015160608401521190613170906146c0565b8260000361318057306101208a01525b60008760200151848151811061319857613198615a7f565b602002602001015190508115613282576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615aae565b9150508061327690615ad2565b6101008c015250613366565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561332e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133529190615aae565b50905061335e81615ad2565b6101008c0152505b61336e61484f565b5050506001016130ab565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156133ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134109190615a53565b90508181108061342e575061010087015161342b9083615a6c565b81105b15613465576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146136fe578461016001516001036136ba577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561369d57600080fd5b505af11580156136b1573d6000803e3d6000fd5b505050506136f6565b6136f68561012001513087610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208601525b60008161379b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137969190615a53565b61379d565b475b9050826137dd576137dd846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166148af9092919063ffffffff16565b61382284608001518560a001518660200151866137fb576000613802565b8961010001515b886040015189606001518c610100015160008b8061381d57508a5b61499f565b6000826138bf5784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ba9190615a53565b6138c1565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506138eb82826158dc565b61010088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526139a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613b31576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff16610100820152845160208082018051909201018652610120820152604051613afc9082906020016157aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613c4357806080015151600003613ba55782516101408401516020850151610100860151613b9e93929161ffff16908061116e565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38660800151876101000151604051613c3a929190918252602082015260400190565b60405180910390a45b613c558360a001518460c00151611140565b8361010001511015613c93576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff918216911615613ecd5761012084015173ffffffffffffffffffffffffffffffffffffffff163014613e1f57836101600151600103613ddb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015613dbe57600080fd5b505af1158015613dd2573d6000803e3d6000fd5b50505050613e17565b613e178461012001513086610100015187610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208501525b613ecd826080015151600014613e355781613ea4565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea49190615b0a565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff1691906148af565b600161018085015260808201515115613ee65780613f55565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f559190615b0a565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff1614613fb457856101a00151613fca565b856101a00151866101000151613fca9190615a6c565b8451602086015160408701516101008a015160c08b0151309190613fef908290611140565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c608001515111614035578d60400151614037565b305b604051602001614072919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b1683526140e29998979695949392600401615b27565b6000604051808303818588803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b505060006101a088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b600061424f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614e9b9092919063ffffffff16565b905080516000148061427057508080602001905181019061427091906159c3565b6112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016111ac565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261435a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611279565b50505050565b60608167ffffffffffffffff81111561437b5761437b615202565b6040519080825280602002602001820160405280156143a4578160200160208202803683370190505b50905060005b828110156143fb57835160140180519085528282815181106143ce576143ce615a7f565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016143aa565b5092915050565b60608167ffffffffffffffff81111561441d5761441d615202565b604051908082528060200260200182016040528015614446578160200160208202803683370190505b50905060005b828110156143fb578351600201805190855282828151811061447057614470615a7f565b61ffff9092166020928302919091019091015260010161444c565b805182516060919067ffffffffffffffff8111156144ab576144ab615202565b6040519080825280602002602001820160405280156144d4578160200160208202803683370190505b50915084826000815181106144eb576144eb615a7f565b60200260200101818152505060005b818110156146b657600085828151811061451657614516615a7f565b602002602001015190506000868360016145309190615a6c565b8151811061454057614540615a7f565b60200260200101519050600089848151811061455e5761455e615a7f565b60200260200101516127106145739190615927565b61ffff16905060008088868151811061458e5761458e615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156145e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146049190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561465f57905b828b0282612710020181848d02028161467a5761467a615959565b049a508a8861468a886001615a6c565b8151811061469a5761469a615a7f565b60209081029190910101525050600190930192506144fa915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361471e576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036148ad576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261493b8482614eb2565b61435a5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526149959085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611279565b61435a84826141ed565b8860ff16600103614acd578715614a58576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015614a3a57600080fd5b505af1158015614a4e573d6000803e3d6000fd5b5050505050614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614a21565b8860ff16600203614c0d578715614b98576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015614b6d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190614b929190615a53565b50614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614b4f565b8860ff16600303614dae578715614c8b576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614b4f565b8015614d05576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614b4f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015614d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b929190615a53565b8860ff16600403614e5e578715614df1576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614a21565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6060614eaa8484600085614f73565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614edc9190615bd3565b6000604051808303816000865af19150503d8060008114614f19576040519150601f19603f3d011682016040523d82523d6000602084013e614f1e565b606091505b5091509150818015614f48575080511580614f48575080806020019051810190614f4891906159c3565b8015614f6a575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b606082471015615005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016111ac565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161502e9190615bd3565b60006040518083038185875af1925050503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b50915091506150818783838761508c565b979650505050505050565b6060831561512257825160000361511b5773ffffffffffffffffffffffffffffffffffffffff85163b61511b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016111ac565b5081614eaa565b614eaa83838151156151375781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac9190615bef565b6000610140828403121561517e57600080fd5b50919050565b6000806040838503121561519757600080fd5b823567ffffffffffffffff808211156151af57600080fd5b6151bb8683870161516b565b935060208501359150808211156151d157600080fd5b508301604081860312156151e457600080fd5b809150509250929050565b61ffff811681146151ff57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561525557615255615202565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156152a2576152a2615202565b604052919050565b600067ffffffffffffffff8211156152c4576152c4615202565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261530157600080fd5b813561531461530f826152aa565b61525b565b81815284602083860101111561532957600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146151ff57600080fd5b60008060008060008060c0878903121561538157600080fd5b863561538c816151ef565b9550602087013567ffffffffffffffff808211156153a957600080fd5b6153b58a838b016152f0565b965060408901359550606089013591506153ce82615346565b9093506080880135925060a088013590808211156153eb57600080fd5b506153f889828a016152f0565b9150509295509295509295565b60006020828403121561541757600080fd5b813567ffffffffffffffff81111561542e57600080fd5b614eaa8482850161516b565b60006020828403121561544c57600080fd5b813561116781615346565b60006020828403121561546957600080fd5b8135611167816151ef565b65ffffffffffff811681146151ff57600080fd5b60006020828403121561549a57600080fd5b813561116781615474565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154da57600080fd5b83018035915067ffffffffffffffff8211156154f557600080fd5b60200191503681900382131561550a57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b80516155de81615346565b919050565b80516155de816151ef565b80516155de81615474565b60005b838110156156145781810151838201526020016155fc565b50506000910152565b600082601f83011261562e57600080fd5b815161563c61530f826152aa565b81815284602083860101111561565157600080fd5b614eaa8260208301602087016155f9565b60006020828403121561567457600080fd5b815167ffffffffffffffff8082111561568c57600080fd5b9083019061014082860312156156a157600080fd5b6156a9615231565b6156b2836155d3565b81526156c0602084016155e3565b60208201526156d1604084016155e3565b60408201526156e2606084016155d3565b60608201526156f3608084016155d3565b608082015261570460a084016155d3565b60a082015260c083015160c082015260e083015160e082015261010061572b8185016155ee565b90820152610120838101518381111561574357600080fd5b61574f8882870161561d565b918301919091525095945050505050565b600081518084526157788160208601602086016155f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526157d160208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516157e8604084018261ffff169052565b50604083015161ffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c083015160e083015260e08301516101008181850152808501519150506101206158938185018365ffffffffffff169052565b840151610140848101529050614eaa610160840182615760565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561113a5761113a6158ad565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615920576159206158ad565b5060010190565b61ffff8281168282160390808211156143fb576143fb6158ad565b808202811582820484141761113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156159d557600080fd5b8151801515811461116757600080fd5b80516dffffffffffffffffffffffffffff811681146155de57600080fd5b600080600060608486031215615a1857600080fd5b615a21846159e5565b9250615a2f602085016159e5565b9150604084015163ffffffff81168114615a4857600080fd5b809150509250925092565b600060208284031215615a6557600080fd5b5051919050565b8082018082111561113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215615ac157600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b0357615b036158ad565b5060000390565b600060208284031215615b1c57600080fd5b815161116781615346565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615b9a610180840182615760565b905082810360e0840152615bae8186615760565b9050828103610100840152615bc38185615760565b9c9b505050505050505050505050565b60008251615be58184602087016155f9565b9190910192915050565b602081526000611167602083018461576056fea26469706673582212202ce6a8f21a153c83c150806f9ce2e260656621d27c2de20b34fdaa1dbce5be3f64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/solcInputs/b02a0ce4f8d2d52325669cdc01d21082.json b/packages/hardhat/deployments/mainnet/solcInputs/b02a0ce4f8d2d52325669cdc01d21082.json new file mode 100644 index 00000000..4439c43c --- /dev/null +++ b/packages/hardhat/deployments/mainnet/solcInputs/b02a0ce4f8d2d52325669cdc01d21082.json @@ -0,0 +1,251 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens.\n *\n * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be\n * stuck.\n *\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] memory,\n uint256[] memory,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Receiver.sol\";\nimport \"../../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@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/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Receiver.sol\";\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\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/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * Perform the swap with tokens already moved to this contract\n */\n function curveExactInputSingleInternal(\n ExactInputSingleParams calldata params\n ) internal returns (uint256 amountOut) {\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 LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n useEth: params.tokenIn == address(0) || isToEth,\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function curveExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (params.tokenIn == address(0)) {\n revert PermitForEthToken();\n }\n\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 return curveExactInputSingleInternal(params);\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\n }\n\n return curveExactInputSingleInternal(params);\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/Ens.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ERC1155Holder} from '@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol';\nimport {ERC721Holder} from '@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol';\nimport {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol';\nimport {IEns} from '../interfaces/IEns.sol';\nimport {IReverseRegistrar} from '../interfaces/external/ens/IReverseRegistrar.sol';\nimport {ENS} from '../interfaces/external/ens/ENS.sol';\nimport {INameWrapper} from '../interfaces/external/ens/INameWrapper.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\n\ncontract Ens is IEns, ERC1155Holder, ERC721Holder {\n function ensSetReverseName(address reverseRegistrar, string memory name) external {\n LibDiamond.enforceIsContractOwner();\n\n IReverseRegistrar(reverseRegistrar).setName(name);\n }\n\n function ensUnwrap(address nameWrapper, bytes32 labelHash) external {\n LibDiamond.enforceIsContractOwner();\n\n INameWrapper(nameWrapper).unwrapETH2LD(labelHash, address(this), address(this));\n }\n\n function ensSetApprovalForAll(address registry, address operator, bool approved) external {\n LibDiamond.enforceIsContractOwner();\n\n ENS(registry).setApprovalForAll(operator, approved);\n }\n\n function ensApprove(address registrar, address spender, uint256 tokenId) external {\n LibDiamond.enforceIsContractOwner();\n\n IERC721(registrar).approve(spender, tokenId);\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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract Stargate is IStargate {\n using SafeERC20 for IERC20;\n\n /**\n * Jump tokens with Stargate with input tokens already moved to this contract\n */\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.token,\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n // NOTE: This lookup is spending 319 gas\n IStargateRouter stargateRouter = IStargateRouter(\n LibWarp.state().stargateComposer.stargateRouter()\n );\n\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\n\n unchecked {\n stargateRouter.swap{value: msg.value}({\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\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\n }\n }\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable {\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.token,\n amount: 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 // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n uint160(params.amountIn),\n params.token\n );\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\n // Transfer tokens from the sender to this contract\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n address(0),\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n unchecked {\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\n _dstChainId: params.dstChainId,\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\n }\n }\n}\n" + }, + "contracts/facets/StarVault.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 {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {IStarVault} from '../interfaces/IStarVault.sol';\n\n/**\n * The StarVault estimates, collects, and tracks fees for partners\n */\ncontract StarVault is IStarVault {\n using SafeERC20 for IERC20;\n\n error InsufficientOwnerBalance(uint256 available);\n\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\n LibStarVault.State storage s = LibStarVault.state();\n\n return s.partnerBalances[partner][token];\n }\n\n function partnerWithdraw(address token) external {\n LibStarVault.State storage s = LibStarVault.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 Withdraw(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 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 LibStarVault.State storage s = LibStarVault.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 emit Withdraw(address(0), token, amount);\n\n if (token == address(0)) {\n // Send ETH\n (bool sent, ) = to.call{value: amount}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(token).safeTransfer(to, amount);\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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * NOTE: The tokens must already have been moved to the first pool\n */\n function uniswapV2LikeExactInputSingleInternal(\n ExactInputSingleParams memory params\n ) internal returns (uint256 amountOut) {\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : params.tokenIn,\n isToEth ? address(0) : params.tokenOut,\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\n }\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 the pool\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pool,\n (uint160)(params.amountIn),\n params.tokenIn\n );\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputInternal(\n ExactInputParams calldata params\n ) internal returns (uint256 amountOut) {\n LibWarp.State storage s = LibWarp.state();\n\n address[] memory tokens = params.tokens;\n uint256 poolLength = params.pools.length;\n bool isFromEth = tokens[0] == address(0);\n bool isToEth = tokens[poolLength] == address(0);\n\n if (isFromEth) {\n tokens[0] = address(s.weth);\n }\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : tokens[0],\n isToEth ? address(0) : tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\n } else {\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\n }\n\n return uniswapV2LikeExactInputInternal(params);\n }\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n // Permit tokens / set allowance\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n\n return uniswapV2LikeExactInputInternal(params);\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 {LibStarVault} from '../libraries/LibStarVault.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\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /**\n * NOTE: The tokens must already have been transferred to the pool\n */\n function uniswapV2ExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n address pair\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address tokenIn = params.tokenIn == address(0) ? address(s.weth) : params.tokenIn;\n address tokenOut = params.tokenOut == address(0) ? address(s.weth) : params.tokenOut;\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (tokenIn > 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 InsufficientOutputAmount();\n }\n\n bool zeroForOne = tokenIn < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.tokenOut == address(0)) {\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn == address(0) ? address(s.weth) : params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\n if (params.tokenIn == address(0)) {\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(address(s.weth)).safeTransfer(pair, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, pair, params.amountIn);\n }\n\n return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\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 return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n /**\n * NOTE: The tokens must already have been transferred to the first pool\n *\n * The path should be rewritten so address(0) is replaced by the WETH address\n */\n function uniswapV2ExactInputInternal(\n ExactInputParams calldata params,\n address[] memory path,\n address[] memory pairs,\n uint256[] memory amounts\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\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 = path[index] < path[indexPlusOne] ? true : false;\n address to = index < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH. 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(path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.path[0],\n params.path[pathLengthMinusOne],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[0] == address(0)) {\n // From ETH\n path[0] = address(s.weth);\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\n }\n\n if (params.path[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer WETH tokens to the first pool\n IERC20(path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n IERC20(path[0]).safeTransferFrom(msg.sender, pairs[0], params.amountIn);\n }\n\n return uniswapV2ExactInputInternal(params, path, pairs, amounts);\n }\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: 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 return uniswapV2ExactInputInternal(params, path, pairs, amounts);\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 if (callback.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n } else {\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\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 /**\n * NOTE: None of these arguments can be trusted\n */\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * KyperSwap V2 callback\n * NOTE: None of these arguments can be trusted\n */\n function swapCallback(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 {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n bool isFromEth = params.tokenIn == address(0);\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\n\n address tokenOut = params.tokenOut == address(0)\n ? address(LibWarp.state().weth)\n : params.tokenOut;\n\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\n\n bool zeroForOne = tokenIn < tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: tokenIn,\n amount: params.amountIn,\n usePermit: usePermit\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokenOut == address(0)) {\n // To ETH, unwrap WETH\n // TODO: This is read twice. Compare gas usage\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH, wrap it\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\n }\n\n function uniswapV3LikeExactInputInternal(\n ExactInputParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n uint256 poolLength = params.pools.length;\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\n address[] memory tokens = params.tokens;\n\n if (params.tokens[0] == address(0)) {\n tokens[0] = address(LibWarp.state().weth);\n }\n\n if (params.tokens[poolLength] == address(0)) {\n tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: payer,\n token: tokens[index],\n amount: amountOut,\n usePermit: usePermit\n })\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokens[poolLength] == address(0)) {\n // To ETH, unwrap\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.tokens[0],\n params.tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH, wrap it\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n }\n\n return uniswapV3LikeExactInputInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputInternal(params, 1);\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 {LibStarVault} from '../libraries/LibStarVault.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';\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\n bytes payload;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n address paramTokenIn;\n uint256 paramAmountIn;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint48 paramDeadline;\n uint256 amount;\n address payer;\n address token;\n /**\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\n */\n uint256 usePermit;\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 if (t.usePermit == 1) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\n }\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 if (t.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\n }\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(\n t.payer,\n params.pools[0],\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\n }\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({\n payer: t.payer,\n token: t.token,\n amount: t.amount,\n usePermit: t.usePermit\n })\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({\n payer: t.payer,\n token: tokenIn,\n amount: t.amount,\n usePermit: t.usePermit\n })\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\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 useEth: isFromEth || isToEth,\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 * Cross-chain callback from Stargate\n *\n * The tokens have already been received by this contract, `t.payer` is set to this contract\n * before `sgReceive` is called by the router.\n *\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\n * same message more than once.\n *\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\n * Stargate composer be compromised, an attacker can drain this contract.\n *\n * If the payload can not be decoded, tokens are left in this contract.\n * If execution runs out of gas, tokens are left in this contract.\n *\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\n * to the recipient.\n *\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\n */\n function sgReceive(\n uint16, // _srcChainId\n bytes memory _srcAddress,\n uint256, // _nonce\n address _token,\n uint256 amountLD,\n bytes memory payload\n ) external {\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\n revert InvalidSgReceiverSender();\n }\n\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\n // From https://ethereum.stackexchange.com/a/50528\n address srcAddress;\n\n assembly {\n srcAddress := mload(add(_srcAddress, 20))\n }\n\n if (srcAddress != address(this)) {\n // NOTE: This assumes that this contract is deployed at the same address on every chain\n revert InvalidSgReceiveSrcAddress();\n }\n\n Params memory params = abi.decode(payload, (Params));\n\n if (params.tokenIn == address(0)) {\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\n // otherwise because `_token` may be different on this chain\n _token = address(0);\n }\n\n try\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\n Params({\n partner: params.partner,\n feeBps: params.feeBps,\n slippageBps: params.slippageBps,\n recipient: params.recipient,\n tokenIn: _token,\n tokenOut: params.tokenOut,\n amountIn: amountLD,\n amountOut: params.amountOut,\n deadline: params.deadline,\n commands: params.commands\n })\n )\n {} catch {\n // Refund tokens to the recipient\n if (_token == address(0)) {\n payable(params.recipient).transfer(amountLD);\n } else {\n IERC20(_token).safeTransfer(params.recipient, amountLD);\n }\n }\n }\n\n /**\n * Jump to another chain using the Stargate bridge\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\n * in this function.\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 * - dstGasForCall (uint32)\n * - tokenOut (address) when `dstGasForCall` > 0\n * - amountOut (uint256) when `dstGasForCall` > 0\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n params.dstGasForCall = stream.readUint32();\n\n if (params.dstGasForCall > 0) {\n // NOTE: `amountIn` is left as zero\n Params memory destParams;\n destParams.partner = t.paramPartner;\n destParams.feeBps = t.paramFeeBps;\n destParams.slippageBps = t.paramSlippageBps;\n destParams.recipient = t.paramRecipient;\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\n // the same address as on this chain\n destParams.tokenIn = t.token;\n destParams.tokenOut = stream.readAddress();\n destParams.amountOut = stream.readUint256();\n destParams.deadline = t.paramDeadline;\n destParams.commands = stream.readBytes();\n params.payload = abi.encode(destParams);\n }\n\n if (t.token != t.paramTokenIn) {\n if (params.payload.length == 0) {\n // If the tokens are being delivered directly to the recipient without a second\n // WarpLink engage, the fee is charged on this chain\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\n // is never charged\n t.amount = LibStarVault.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n }\n\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n t.payer,\n address(this),\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\n\n // Update the payer to this contract\n // TODO: Is this value ever read?\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\n IERC20(t.token).forceApprove(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\n t.amount\n );\n }\n\n t.jumped = 1;\n\n // Swap on the composer if there is a payload, else the router\n IStargateRouter(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\n ).swap{\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\n }({\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\n // more on the other chain. It also assumes the tokens are of nearly equal value\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: params.dstGasForCall,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n // NOTE: This assumes the contract is deployed at the same address on every chain.\n // If this is not the case, a new param needs to be added with the next WarpLink address\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\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\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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable {\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.usePermit = 1;\n\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 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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\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';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\n\ncontract InitLibWarp {\n function init(address weth, address permit2, address stargateComposer) public {\n LibWarp.State storage s = LibWarp.state();\n\n s.weth = IWETH(weth);\n s.permit2 = IPermit2(permit2);\n s.stargateComposer = IStargateComposer(stargateComposer);\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/ens/ENS.sol": { + "content": "// SPDX-License-Identifier: UNKNOWN\npragma solidity >=0.8.4;\n\ninterface ENS {\n function setApprovalForAll(address operator, bool approved) external;\n}\n" + }, + "contracts/interfaces/external/ens/INameWrapper.sol": { + "content": "// SPDX-License-Identifier: UNKNOWN\npragma solidity ^0.8.19;\n\ninterface INameWrapper {\n function unwrapETH2LD(bytes32 label, address newRegistrant, address newController) external;\n}\n" + }, + "contracts/interfaces/external/ens/IReverseRegistrar.sol": { + "content": "// SPDX-License-Identifier: UNKNOWN\npragma solidity ^0.8.19;\n\ninterface IReverseRegistrar {\n function setName(string memory name) external returns (bytes32);\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(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy,\n bool use_eth\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\n// Kind 4, uint256s with no return value\n// Example v0.2.15, \"Pool for USDT/BTC/ETH or similar\"\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\ninterface ICurvePoolKind4 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\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/IStargateComposer.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\nimport {IStargateRouter} from './IStargateRouter.sol';\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateComposer is IStargateRouter {\n function stargateRouter() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/IStargateReceiver.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\n\ninterface IStargateReceiver {\n function sgReceive(\n uint16 _srcChainId, // the remote chainId sending the tokens\n bytes memory _srcAddress, // the remote Bridge address\n uint256 _nonce,\n address _token, // the token contract on the local chain\n uint256 amountLD, // the qty of local _token contract tokens\n bytes memory payload\n ) 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/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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n /**\n * A function expecting a permit was used when the input token is ETH\n */\n error PermitForEthToken();\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 curveExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params\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/IEns.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IEns {\n function ensSetReverseName(address reverseRegistrar, string memory name) external;\n\n function ensUnwrap(address nameWrapper, bytes32 labelHash) external;\n\n function ensSetApprovalForAll(address registry, address operator, bool approved) external;\n\n function ensApprove(address registrar, address spender, uint256 tokenId) external;\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/ILibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibCurve {\n error UnhandledPoolKind();\n}\n" + }, + "contracts/interfaces/ILibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n}\n" + }, + "contracts/interfaces/ILibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n}\n" + }, + "contracts/interfaces/ILibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n}\n" + }, + "contracts/interfaces/IStargate.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\n\ninterface IStargate is ILibStarVault {\n error InsufficientEthValue();\n\n struct JumpTokenParams {\n address token;\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n struct JumpNativeParams {\n /**\n * The amount in is passed to distinguish the amount to bridge from the fee\n */\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable;\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\n}\n" + }, + "contracts/interfaces/IStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IStarVault {\n error EthTransferFailed();\n\n event Withdraw(address indexed partner, address indexed token, uint256 amount);\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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Like is ILibStarVault, ILibWarp {\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 ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Router is ILibStarVault, ILibWarp {\n error EthTransferFailed();\n error ZeroAmountOut();\n error IncorrectEthValue();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\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 error InvalidSgReceiverSender();\n error InvalidSgReceiveSrcAddress();\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 calldata params) external payable;\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable;\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibCurve\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 bool useEth\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 if (useEth) {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\n } else {\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\n }\n } else if (kind == 4) {\n if (underlying) {\n revert UnhandledPoolKind();\n } else {\n ICurvePoolKind4(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/LibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * NOTE: Events and errors must be copied to ILibStarVault\n */\nlibrary LibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n\n struct State {\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 uint256 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n /**\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\n * removed to save gas.\n */\n unchecked {\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\n\n assembly {\n s.slot := storagePosition\n }\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 protocolFee\n ) internal {\n State storage s = state();\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit Fee(partner, token, partnerFee, protocolFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint256 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 feeProtocol = feeTotal - feePartner;\n\n if (feeProtocol > 0) {\n registerCollectedFee(partner, token, feePartner, feeProtocol);\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\n/**\n * NOTE: Events and errors must be copied to ILibUniV3Like\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 * Whether to use a permit transfer (0 or 1)\n */\n uint256 usePermit;\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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibWarp\n */\nlibrary LibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateComposer stargateComposer;\n }\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\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/c6735d71c8937120ee5b82bc32fb5df3.json b/packages/hardhat/deployments/mainnet/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json new file mode 100644 index 00000000..cf1aa121 --- /dev/null +++ b/packages/hardhat/deployments/mainnet/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json @@ -0,0 +1,170 @@ +{ + "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" + }, + "@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * Perform the swap with tokens already moved to this contract\n */\n function curveExactInputSingleInternal(\n ExactInputSingleParams calldata params\n ) internal returns (uint256 amountOut) {\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 LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n useEth: params.tokenIn == address(0) || isToEth,\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function curveExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (params.tokenIn == address(0)) {\n revert PermitForEthToken();\n }\n\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 return curveExactInputSingleInternal(params);\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\n }\n\n return curveExactInputSingleInternal(params);\n }\n}\n" + }, + "contracts/facets/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract Stargate is IStargate {\n using SafeERC20 for IERC20;\n\n /**\n * Jump tokens with Stargate with input tokens already moved to this contract\n */\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.token,\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n // NOTE: This lookup is spending 319 gas\n IStargateRouter stargateRouter = IStargateRouter(\n LibWarp.state().stargateComposer.stargateRouter()\n );\n\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\n\n unchecked {\n stargateRouter.swap{value: msg.value}({\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\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\n }\n }\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable {\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.token,\n amount: 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 // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n uint160(params.amountIn),\n params.token\n );\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\n // Transfer tokens from the sender to this contract\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n address(0),\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n unchecked {\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\n _dstChainId: params.dstChainId,\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * NOTE: The tokens must already have been moved to the first pool\n */\n function uniswapV2LikeExactInputSingleInternal(\n ExactInputSingleParams memory params\n ) internal returns (uint256 amountOut) {\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : params.tokenIn,\n isToEth ? address(0) : params.tokenOut,\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\n }\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 the pool\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pool,\n (uint160)(params.amountIn),\n params.tokenIn\n );\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputInternal(\n ExactInputParams calldata params\n ) internal returns (uint256 amountOut) {\n LibWarp.State storage s = LibWarp.state();\n\n address[] memory tokens = params.tokens;\n uint256 poolLength = params.pools.length;\n bool isFromEth = tokens[0] == address(0);\n bool isToEth = tokens[poolLength] == address(0);\n\n if (isFromEth) {\n tokens[0] = address(s.weth);\n }\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : tokens[0],\n isToEth ? address(0) : tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\n } else {\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\n }\n\n return uniswapV2LikeExactInputInternal(params);\n }\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n // Permit tokens / set allowance\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n\n return uniswapV2LikeExactInputInternal(params);\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 {LibStarVault} from '../libraries/LibStarVault.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\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /**\n * NOTE: The tokens must already have been transferred to the pool\n */\n function uniswapV2ExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n address pair\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address tokenIn = params.tokenIn == address(0) ? address(s.weth) : params.tokenIn;\n address tokenOut = params.tokenOut == address(0) ? address(s.weth) : params.tokenOut;\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (tokenIn > 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 InsufficientOutputAmount();\n }\n\n bool zeroForOne = tokenIn < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.tokenOut == address(0)) {\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn == address(0) ? address(s.weth) : params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\n if (params.tokenIn == address(0)) {\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(address(s.weth)).safeTransfer(pair, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, pair, params.amountIn);\n }\n\n return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\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 return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n /**\n * NOTE: The tokens must already have been transferred to the first pool\n *\n * The path should be rewritten so address(0) is replaced by the WETH address\n */\n function uniswapV2ExactInputInternal(\n ExactInputParams calldata params,\n address[] memory path,\n address[] memory pairs,\n uint256[] memory amounts\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\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 = path[index] < path[indexPlusOne] ? true : false;\n address to = index < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH. 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(path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.path[0],\n params.path[pathLengthMinusOne],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[0] == address(0)) {\n // From ETH\n path[0] = address(s.weth);\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\n }\n\n if (params.path[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer WETH tokens to the first pool\n IERC20(path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n IERC20(path[0]).safeTransferFrom(msg.sender, pairs[0], params.amountIn);\n }\n\n return uniswapV2ExactInputInternal(params, path, pairs, amounts);\n }\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: 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 return uniswapV2ExactInputInternal(params, path, pairs, amounts);\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 if (callback.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n } else {\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\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 /**\n * NOTE: None of these arguments can be trusted\n */\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * KyperSwap V2 callback\n * NOTE: None of these arguments can be trusted\n */\n function swapCallback(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 {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n bool isFromEth = params.tokenIn == address(0);\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\n\n address tokenOut = params.tokenOut == address(0)\n ? address(LibWarp.state().weth)\n : params.tokenOut;\n\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\n\n bool zeroForOne = tokenIn < tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: tokenIn,\n amount: params.amountIn,\n usePermit: usePermit\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokenOut == address(0)) {\n // To ETH, unwrap WETH\n // TODO: This is read twice. Compare gas usage\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH, wrap it\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\n }\n\n function uniswapV3LikeExactInputInternal(\n ExactInputParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n uint256 poolLength = params.pools.length;\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\n address[] memory tokens = params.tokens;\n\n if (params.tokens[0] == address(0)) {\n tokens[0] = address(LibWarp.state().weth);\n }\n\n if (params.tokens[poolLength] == address(0)) {\n tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: payer,\n token: tokens[index],\n amount: amountOut,\n usePermit: usePermit\n })\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokens[poolLength] == address(0)) {\n // To ETH, unwrap\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.tokens[0],\n params.tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH, wrap it\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n }\n\n return uniswapV3LikeExactInputInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputInternal(params, 1);\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 {LibStarVault} from '../libraries/LibStarVault.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';\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\n bytes payload;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n address paramTokenIn;\n uint256 paramAmountIn;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint48 paramDeadline;\n uint256 amount;\n address payer;\n address token;\n /**\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\n */\n uint256 usePermit;\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 if (t.usePermit == 1) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\n }\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 if (t.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\n }\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(\n t.payer,\n params.pools[0],\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\n }\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({\n payer: t.payer,\n token: t.token,\n amount: t.amount,\n usePermit: t.usePermit\n })\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({\n payer: t.payer,\n token: tokenIn,\n amount: t.amount,\n usePermit: t.usePermit\n })\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\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 useEth: isFromEth || isToEth,\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 * Cross-chain callback from Stargate\n *\n * The tokens have already been received by this contract, `t.payer` is set to this contract\n * before `sgReceive` is called by the router.\n *\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\n * same message more than once.\n *\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\n * Stargate composer be compromised, an attacker can drain this contract.\n *\n * If the payload can not be decoded, tokens are left in this contract.\n * If execution runs out of gas, tokens are left in this contract.\n *\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\n * to the recipient.\n *\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\n */\n function sgReceive(\n uint16, // _srcChainId\n bytes memory _srcAddress,\n uint256, // _nonce\n address _token,\n uint256 amountLD,\n bytes memory payload\n ) external {\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\n revert InvalidSgReceiverSender();\n }\n\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\n // From https://ethereum.stackexchange.com/a/50528\n address srcAddress;\n\n assembly {\n srcAddress := mload(add(_srcAddress, 20))\n }\n\n if (srcAddress != address(this)) {\n // NOTE: This assumes that this contract is deployed at the same address on every chain\n revert InvalidSgReceiveSrcAddress();\n }\n\n Params memory params = abi.decode(payload, (Params));\n\n if (params.tokenIn == address(0)) {\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\n // otherwise because `_token` may be different on this chain\n _token = address(0);\n }\n\n try\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\n Params({\n partner: params.partner,\n feeBps: params.feeBps,\n slippageBps: params.slippageBps,\n recipient: params.recipient,\n tokenIn: _token,\n tokenOut: params.tokenOut,\n amountIn: amountLD,\n amountOut: params.amountOut,\n deadline: params.deadline,\n commands: params.commands\n })\n )\n {} catch {\n // Refund tokens to the recipient\n if (_token == address(0)) {\n payable(params.recipient).transfer(amountLD);\n } else {\n IERC20(_token).safeTransfer(params.recipient, amountLD);\n }\n }\n }\n\n /**\n * Jump to another chain using the Stargate bridge\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\n * in this function.\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 * - dstGasForCall (uint32)\n * - tokenOut (address) when `dstGasForCall` > 0\n * - amountOut (uint256) when `dstGasForCall` > 0\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n params.dstGasForCall = stream.readUint32();\n\n if (params.dstGasForCall > 0) {\n // NOTE: `amountIn` is left as zero\n Params memory destParams;\n destParams.partner = t.paramPartner;\n destParams.feeBps = t.paramFeeBps;\n destParams.slippageBps = t.paramSlippageBps;\n destParams.recipient = t.paramRecipient;\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\n // the same address as on this chain\n destParams.tokenIn = t.token;\n destParams.tokenOut = stream.readAddress();\n destParams.amountOut = stream.readUint256();\n destParams.deadline = t.paramDeadline;\n destParams.commands = stream.readBytes();\n params.payload = abi.encode(destParams);\n }\n\n if (t.token != t.paramTokenIn) {\n if (params.payload.length == 0) {\n // If the tokens are being delivered directly to the recipient without a second\n // WarpLink engage, the fee is charged on this chain\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\n // is never charged\n t.amount = LibStarVault.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n }\n\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n t.payer,\n address(this),\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\n\n // Update the payer to this contract\n // TODO: Is this value ever read?\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\n IERC20(t.token).forceApprove(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\n t.amount\n );\n }\n\n t.jumped = 1;\n\n // Swap on the composer if there is a payload, else the router\n IStargateRouter(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\n ).swap{\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\n }({\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\n // more on the other chain. It also assumes the tokens are of nearly equal value\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: params.dstGasForCall,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n // NOTE: This assumes the contract is deployed at the same address on every chain.\n // If this is not the case, a new param needs to be added with the next WarpLink address\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\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\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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable {\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.usePermit = 1;\n\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 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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\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(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy,\n bool use_eth\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\n// Kind 4, uint256s with no return value\n// Example v0.2.15, \"Pool for USDT/BTC/ETH or similar\"\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\ninterface ICurvePoolKind4 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\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/IStargateComposer.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\nimport {IStargateRouter} from './IStargateRouter.sol';\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateComposer is IStargateRouter {\n function stargateRouter() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/IStargateReceiver.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\n\ninterface IStargateReceiver {\n function sgReceive(\n uint16 _srcChainId, // the remote chainId sending the tokens\n bytes memory _srcAddress, // the remote Bridge address\n uint256 _nonce,\n address _token, // the token contract on the local chain\n uint256 amountLD, // the qty of local _token contract tokens\n bytes memory payload\n ) 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n /**\n * A function expecting a permit was used when the input token is ETH\n */\n error PermitForEthToken();\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 curveExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/ILibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibCurve {\n error UnhandledPoolKind();\n}\n" + }, + "contracts/interfaces/ILibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n}\n" + }, + "contracts/interfaces/ILibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n}\n" + }, + "contracts/interfaces/ILibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n}\n" + }, + "contracts/interfaces/IStargate.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\n\ninterface IStargate is ILibStarVault {\n error InsufficientEthValue();\n\n struct JumpTokenParams {\n address token;\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n struct JumpNativeParams {\n /**\n * The amount in is passed to distinguish the amount to bridge from the fee\n */\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable;\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Like is ILibStarVault, ILibWarp {\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 ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Router is ILibStarVault, ILibWarp {\n error EthTransferFailed();\n error ZeroAmountOut();\n error IncorrectEthValue();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\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 error InvalidSgReceiverSender();\n error InvalidSgReceiveSrcAddress();\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 calldata params) external payable;\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable;\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibCurve\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 bool useEth\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 if (useEth) {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\n } else {\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\n }\n } else if (kind == 4) {\n if (underlying) {\n revert UnhandledPoolKind();\n } else {\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * NOTE: Events and errors must be copied to ILibStarVault\n */\nlibrary LibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n\n struct State {\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 uint256 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n /**\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\n * removed to save gas.\n */\n unchecked {\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\n\n assembly {\n s.slot := storagePosition\n }\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 protocolFee\n ) internal {\n State storage s = state();\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit Fee(partner, token, partnerFee, protocolFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint256 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 feeProtocol = feeTotal - feePartner;\n\n if (feeProtocol > 0) {\n registerCollectedFee(partner, token, feePartner, feeProtocol);\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\n/**\n * NOTE: Events and errors must be copied to ILibUniV3Like\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 * Whether to use a permit transfer (0 or 1)\n */\n uint256 usePermit;\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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibWarp\n */\nlibrary LibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateComposer stargateComposer;\n }\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\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 b9df3eaa..ee8d4704 100644 --- a/packages/hardhat/deployments/optimism/Curve.json +++ b/packages/hardhat/deployments/optimism/Curve.json @@ -1,5 +1,5 @@ { - "address": "0x58008F004bC571d610643E2979621884E01A3FBf", + "address": "0xE629194E5f465Fe357ae6a2C92F663F9bdA1247b", "abi": [ { "inputs": [], @@ -38,6 +38,11 @@ "name": "InsufficientOutputAmount", "type": "error" }, + { + "inputs": [], + "name": "PermitForEthToken", + "type": "error" + }, { "inputs": [], "name": "UnhandledPoolKind", @@ -116,6 +121,97 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "curveExactInputSingle", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -213,7 +309,7 @@ "type": "tuple" } ], - "name": "curveExactInputSingle", + "name": "curveExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -225,28 +321,28 @@ "type": "function" } ], - "transactionHash": "0x1bf80c090ec306ae725f3b938da49915ba21d7b12bd51f78ceb238e10ef844c1", + "transactionHash": "0x410d3d85be3ab9074058c78bb6aa0017ae0d16db29ff27fa33e04d81ff02f665", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x58008F004bC571d610643E2979621884E01A3FBf", - "transactionIndex": 4, - "gasUsed": "1361268", + "contractAddress": "0xE629194E5f465Fe357ae6a2C92F663F9bdA1247b", + "transactionIndex": 6, + "gasUsed": "1468512", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xa5ff252332abcc69d0bd9d8227a31657d8f6af235524ea5a6743d25af3552930", - "transactionHash": "0x1bf80c090ec306ae725f3b938da49915ba21d7b12bd51f78ceb238e10ef844c1", + "blockHash": "0x2af095857eff5983a23e7505cf6dbf0ba785ece18a1810b6967cf0a0921d4e76", + "transactionHash": "0x410d3d85be3ab9074058c78bb6aa0017ae0d16db29ff27fa33e04d81ff02f665", "logs": [], - "blockNumber": 111391447, - "cumulativeGasUsed": "2163507", + "blockNumber": 111825983, + "cumulativeGasUsed": "2362126", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 11, - "solcInputHash": "ebf955869df0dfecc3a0eb12547e8afc", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 useEth: params.tokenIn == address(0) || isToEth,\\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0x6d796fc46a41bd9fe76ae989d273f90aa0298f993f5c77cf481f5968fad21474\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\\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\":\"0x88d6dcf171951cf8e3f3488ef5d66a953614ae48926f9ace36d58b095bf9dc84\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506117d5806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b6100366100313660046113ad565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906114ed565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff9091169161066b565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b90890189611506565b6040518563ffffffff1660e01b815260040161026a9493929190611572565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b6103cc856101800151866101a001518760600151348961014001518a61016001518b6000015160008073ffffffffffffffffffffffffffffffffffffffff168e60e0015173ffffffffffffffffffffffffffffffffffffffff1614806103c757508a5b6107df565b60008261046d576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046891906114ed565b61046f565b475b905061047b8282611663565b935061048f86602001518760a00151610cdb565b8410156104c8576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ea8660c00151876101000151886080015161ffff16896020015188610d0b565b93508215610596576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610550576040519150601f19603f3d011682016040523d82523d6000602084013e610555565b606091505b5050905080610590576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506105ca565b6105ca86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610dc49092919063ffffffff16565b85610100015173ffffffffffffffffffffffffffffffffffffffff168660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f389600001518860405161065a929190918252602082015260400190565b60405180910390a450505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106f78482610e1f565b6107d95760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526107cf9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610ee0565b6107d98482610ee0565b50505050565b8860ff1660010361090d578715610898576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b5050505050610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610861565b8860ff16600203610a4d5787156109d8576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156109ad573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109d291906114ed565b50610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df0212490889060840161098f565b8860ff16600303610bee578715610acb576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b90889060840161098f565b8015610b45576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a40161098f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015610bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d291906114ed565b8860ff16600403610c9e578715610c31576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610861565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6000612710610cea8382611676565b610cf89061ffff1685611698565b610d0291906116af565b90505b92915050565b60006107d0841115610d52576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610d64575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610d9a5760646032840204610d9d565b60005b9050808303838214610db557610db58a8a8484610fef565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e1a9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161074d565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e49919061170e565b6000604051808303816000865af19150503d8060008114610e86576040519150601f19603f3d011682016040523d82523d6000602084013e610e8b565b606091505b5091509150818015610eb5575080511580610eb5575080806020019051810190610eb5919061172a565b8015610ed7575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166110b79092919063ffffffff16565b9050805160001480610f63575080806020019051810190610f63919061172a565b610e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d49565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60606110c684846000856110ce565b949350505050565b606082471015611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d49565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611189919061170e565b60006040518083038185875af1925050503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b50915091506111dc878383876111e7565b979650505050505050565b6060831561127d5782516000036112765773ffffffffffffffffffffffffffffffffffffffff85163b611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d49565b50816110c6565b6110c683838151156112925781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d49919061174e565b6040516101c0810167ffffffffffffffff81118282101715611311577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133b57600080fd5b919050565b803561ffff8116811461133b57600080fd5b803565ffffffffffff8116811461133b57600080fd5b803560ff8116811461133b57600080fd5b801515811461138757600080fd5b50565b803561133b81611379565b6000604082840312156113a757600080fd5b50919050565b6000808284036101e08112156113c257600080fd5b6101c0808212156113d257600080fd5b6113da6112c6565b915084358252602085013560208301526113f660408601611317565b604083015261140760608601611317565b606083015261141860808601611340565b608083015261142960a08601611340565b60a083015261143a60c08601611317565b60c083015261144b60e08601611317565b60e083015261010061145e818701611317565b90830152610120611470868201611352565b90830152610140611482868201611368565b90830152610160611494868201611368565b908301526101806114a6868201611368565b908301526101a06114b886820161138a565b9083015290925083013567ffffffffffffffff8111156114d757600080fd5b6114e385828601611395565b9150509250929050565b6000602082840312156114ff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261153b57600080fd5b83018035915067ffffffffffffffff82111561155657600080fd5b60200191503681900382131561156b57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d0557610d05611634565b61ffff82811682821603908082111561169157611691611634565b5092915050565b8082028115828204841417610d0557610d05611634565b6000826116e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156117055781810151838201526020016116ed565b50506000910152565b600082516117208184602087016116ea565b9190910192915050565b60006020828403121561173c57600080fd5b815161174781611379565b9392505050565b602081526000825180602084015261176d8160408501602087016116ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212204f164ad9f74d85efb515fab3ce059723b15ff2d1b51c1308c6989e26aff5f0c564736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b6100366100313660046113ad565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a91906114ed565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff9091169161066b565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b90890189611506565b6040518563ffffffff1660e01b815260040161026a9493929190611572565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b6103cc856101800151866101a001518760600151348961014001518a61016001518b6000015160008073ffffffffffffffffffffffffffffffffffffffff168e60e0015173ffffffffffffffffffffffffffffffffffffffff1614806103c757508a5b6107df565b60008261046d576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610444573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046891906114ed565b61046f565b475b905061047b8282611663565b935061048f86602001518760a00151610cdb565b8410156104c8576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ea8660c00151876101000151886080015161ffff16896020015188610d0b565b93508215610596576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610550576040519150601f19603f3d011682016040523d82523d6000602084013e610555565b606091505b5050905080610590576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506105ca565b6105ca86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610dc49092919063ffffffff16565b85610100015173ffffffffffffffffffffffffffffffffffffffff168660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f389600001518860405161065a929190918252602082015260400190565b60405180910390a450505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106f78482610e1f565b6107d95760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526107cf9085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610ee0565b6107d98482610ee0565b50505050565b8860ff1660010361090d578715610898576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b5050505050610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610861565b8860ff16600203610a4d5787156109d8576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156109ad573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109d291906114ed565b50610cd0565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df0212490889060840161098f565b8860ff16600303610bee578715610acb576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b90889060840161098f565b8015610b45576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a40161098f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015610bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d291906114ed565b8860ff16600403610c9e578715610c31576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610861565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6000612710610cea8382611676565b610cf89061ffff1685611698565b610d0291906116af565b90505b92915050565b60006107d0841115610d52576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610d64575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610d9a5760646032840204610d9d565b60005b9050808303838214610db557610db58a8a8484610fef565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e1a9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161074d565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e49919061170e565b6000604051808303816000865af19150503d8060008114610e86576040519150601f19603f3d011682016040523d82523d6000602084013e610e8b565b606091505b5091509150818015610eb5575080511580610eb5575080806020019051810190610eb5919061172a565b8015610ed7575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166110b79092919063ffffffff16565b9050805160001480610f63575080806020019051810190610f63919061172a565b610e1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d49565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60606110c684846000856110ce565b949350505050565b606082471015611160576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d49565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611189919061170e565b60006040518083038185875af1925050503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b50915091506111dc878383876111e7565b979650505050505050565b6060831561127d5782516000036112765773ffffffffffffffffffffffffffffffffffffffff85163b611276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d49565b50816110c6565b6110c683838151156112925781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d49919061174e565b6040516101c0810167ffffffffffffffff81118282101715611311577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133b57600080fd5b919050565b803561ffff8116811461133b57600080fd5b803565ffffffffffff8116811461133b57600080fd5b803560ff8116811461133b57600080fd5b801515811461138757600080fd5b50565b803561133b81611379565b6000604082840312156113a757600080fd5b50919050565b6000808284036101e08112156113c257600080fd5b6101c0808212156113d257600080fd5b6113da6112c6565b915084358252602085013560208301526113f660408601611317565b604083015261140760608601611317565b606083015261141860808601611340565b608083015261142960a08601611340565b60a083015261143a60c08601611317565b60c083015261144b60e08601611317565b60e083015261010061145e818701611317565b90830152610120611470868201611352565b90830152610140611482868201611368565b90830152610160611494868201611368565b908301526101806114a6868201611368565b908301526101a06114b886820161138a565b9083015290925083013567ffffffffffffffff8111156114d757600080fd5b6114e385828601611395565b9150509250929050565b6000602082840312156114ff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261153b57600080fd5b83018035915067ffffffffffffffff82111561155657600080fd5b60200191503681900382131561156b57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d0557610d05611634565b61ffff82811682821603908082111561169157611691611634565b5092915050565b8082028115828204841417610d0557610d05611634565b6000826116e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156117055781810151838201526020016116ed565b50506000910152565b600082516117208184602087016116ea565b9190910192915050565b60006020828403121561173c57600080fd5b815161174781611379565b9392505050565b602081526000825180602084015261176d8160408501602087016116ea565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212204f164ad9f74d85efb515fab3ce059723b15ff2d1b51c1308c6989e26aff5f0c564736f6c63430008130033", + "numDeployments": 12, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermitForEthToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"name\":\"curveExactInputSingle\",\"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\":\"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\":\"curveExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}],\"PermitForEthToken()\":[{\"notice\":\"A function expecting a permit was used when the input token is ETH\"}]},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\\n * Perform the swap with tokens already moved to this contract\\n */\\n function curveExactInputSingleInternal(\\n ExactInputSingleParams calldata params\\n ) internal returns (uint256 amountOut) {\\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 LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n useEth: params.tokenIn == address(0) || isToEth,\\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function curveExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (params.tokenIn == address(0)) {\\n revert PermitForEthToken();\\n }\\n\\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 return curveExactInputSingleInternal(params);\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\\n }\\n\\n return curveExactInputSingleInternal(params);\\n }\\n}\\n\",\"keccak256\":\"0x14d74eb8ac6efa00532e5de577c6b6ca66866e6991a220986ca7733d920de561\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n /**\\n * A function expecting a permit was used when the input token is ETH\\n */\\n error PermitForEthToken();\\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 curveExactInputSinglePermit(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xd034586f038b6ea01e6ce9d6497d203ef8cc5d221884f1a6f608ce08bae51904\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506119c8806100206000396000f3fe6080604052600436106100295760003560e01c806356bf88f01461002e578063aef417b114610053575b600080fd5b61004161003c366004611598565b610066565b60405190815260200160405180910390f35b6100416100613660046115f0565b610348565b60008061007a610100850160e0860161160d565b73ffffffffffffffffffffffffffffffffffffffff16036100c7576040517f53e40ce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a6100da608085016060860161160d565b84356100ed610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff169190610430565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925273ffffffffffffffffffffffffffffffffffffffff90921691632b67b57091339190819060608201908190610174906101008c01908c0161160d565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016101ab6101408b016101208c0161164a565b65ffffffffffff908116825289351660209182015290825230908201526040016101dd61014089016101208a0161164a565b65ffffffffffff1690526101f46020870187611672565b6040518563ffffffff1660e01b815260040161021394939291906116de565b600060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505061026c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333086356102a0610100890160e08a0161160d565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561031e57600080fd5b505af1158015610332573d6000803e3d6000fd5b5050505061033f836105a4565b90505b92915050565b600061035c6101408301610120840161164a565b65ffffffffffff1642111561039d576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103b0610100840160e0850161160d565b73ffffffffffffffffffffffffffffffffffffffff1614610427576103f16103de608084016060850161160d565b83356100ed610100860160e0870161160d565b61042733308435610409610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff16929190610a43565b610342826105a4565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526104bc8482610aa1565b61059e5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526105949085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610b62565b61059e8482610b62565b50505050565b600080806105ba6101208501610100860161160d565b73ffffffffffffffffffffffffffffffffffffffff16149050600081610681576105ec6101208501610100860161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c91906117a0565b610683565b475b905061073661069a6101a0860161018087016117b9565b6106ac6101c087016101a088016117ed565b6106bc608088016060890161160d565b346106cf6101608a016101408b016117b9565b6106e16101808b016101608c016117b9565b8a6000013560008073ffffffffffffffffffffffffffffffffffffffff168d60e0016020810190610712919061160d565b73ffffffffffffffffffffffffffffffffffffffff16148061073157508a5b610c7b565b6000826107e45761074f6101208601610100870161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df91906117a0565b6107e6565b475b90506107f28282611839565b9350610811602086013561080c60c0880160a0890161184c565b611177565b84101561084a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088e61085d60e0870160c0880161160d565b61086f6101208801610100890161160d565b61087f60a0890160808a0161184c565b61ffff1688602001358861119e565b935082156109455760006108a8606087016040880161160d565b73ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146108ff576040519150601f19603f3d011682016040523d82523d6000602084013e610904565b606091505b505090508061093f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610988565b610988610958606087016040880161160d565b8561096b61012089016101008a0161160d565b73ffffffffffffffffffffffffffffffffffffffff169190611252565b61099a6101208601610100870161160d565b73ffffffffffffffffffffffffffffffffffffffff166109c1610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff166109e760e0880160c0890161160d565b60408051893581526020810189905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261059e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610512565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610acb9190611894565b6000604051808303816000865af19150503d8060008114610b08576040519150601f19603f3d011682016040523d82523d6000602084013e610b0d565b606091505b5091509150818015610b37575080511580610b37575080806020019051810190610b3791906118b0565b8015610b59575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610bc4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112a89092919063ffffffff16565b9050805160001480610be5575080806020019051810190610be591906118b0565b610c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b8860ff16600103610da9578715610d34576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015610d1657600080fd5b505af1158015610d2a573d6000803e3d6000fd5b505050505061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610cfd565b8860ff16600203610ee9578715610e74576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015610e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b5061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610e2b565b8860ff1660030361108a578715610f67576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401610e2b565b8015610fe1576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401610e2b565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015611066573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b8860ff1660040361113a5787156110cd576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610cfd565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600061271061118683826118cd565b6111949061ffff16856118ef565b61033f9190611906565b60006107d08411156111e0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d06004820152602401610c6d565b600082848111156111f2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611228576064603284020461122b565b60005b9050808303838214611243576112438a8a84846112bf565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c769084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610512565b60606112b78484600085611387565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606082471015611419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c6d565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516114429190611894565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b5091509150611495878383876114a0565b979650505050505050565b6060831561153657825160000361152f5773ffffffffffffffffffffffffffffffffffffffff85163b61152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c6d565b50816112b7565b6112b7838381511561154b5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9190611941565b60006101c0828403121561159257600080fd5b50919050565b6000806101e083850312156115ac57600080fd5b6115b6848461157f565b91506101c083013567ffffffffffffffff8111156115d357600080fd5b8301604081860312156115e557600080fd5b809150509250929050565b60006101c0828403121561160357600080fd5b61033f838361157f565b60006020828403121561161f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461164357600080fd5b9392505050565b60006020828403121561165c57600080fd5b813565ffffffffffff8116811461164357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126116a757600080fd5b83018035915067ffffffffffffffff8211156116c257600080fd5b6020019150368190038213156116d757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156117b257600080fd5b5051919050565b6000602082840312156117cb57600080fd5b813560ff8116811461164357600080fd5b80151581146117ea57600080fd5b50565b6000602082840312156117ff57600080fd5b8135611643816117dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156103425761034261180a565b60006020828403121561185e57600080fd5b813561ffff8116811461164357600080fd5b60005b8381101561188b578181015183820152602001611873565b50506000910152565b600082516118a6818460208701611870565b9190910192915050565b6000602082840312156118c257600080fd5b8151611643816117dc565b61ffff8281168282160390808211156118e8576118e861180a565b5092915050565b80820281158282048414176103425761034261180a565b60008261193c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6020815260008251806020840152611960816040850160208701611870565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202b55d2f11aa7f1395a3e9c79ad5594ecdb6d8158214c767aed2d3da3a5500d1264736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c806356bf88f01461002e578063aef417b114610053575b600080fd5b61004161003c366004611598565b610066565b60405190815260200160405180910390f35b6100416100613660046115f0565b610348565b60008061007a610100850160e0860161160d565b73ffffffffffffffffffffffffffffffffffffffff16036100c7576040517f53e40ce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a6100da608085016060860161160d565b84356100ed610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff169190610430565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925273ffffffffffffffffffffffffffffffffffffffff90921691632b67b57091339190819060608201908190610174906101008c01908c0161160d565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016101ab6101408b016101208c0161164a565b65ffffffffffff908116825289351660209182015290825230908201526040016101dd61014089016101208a0161164a565b65ffffffffffff1690526101f46020870187611672565b6040518563ffffffff1660e01b815260040161021394939291906116de565b600060405180830381600087803b15801561022d57600080fd5b505af1158015610241573d6000803e3d6000fd5b5050505061026c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333086356102a0610100890160e08a0161160d565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561031e57600080fd5b505af1158015610332573d6000803e3d6000fd5b5050505061033f836105a4565b90505b92915050565b600061035c6101408301610120840161164a565b65ffffffffffff1642111561039d576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103b0610100840160e0850161160d565b73ffffffffffffffffffffffffffffffffffffffff1614610427576103f16103de608084016060850161160d565b83356100ed610100860160e0870161160d565b61042733308435610409610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff16929190610a43565b610342826105a4565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526104bc8482610aa1565b61059e5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526105949085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610b62565b61059e8482610b62565b50505050565b600080806105ba6101208501610100860161160d565b73ffffffffffffffffffffffffffffffffffffffff16149050600081610681576105ec6101208501610100860161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c91906117a0565b610683565b475b905061073661069a6101a0860161018087016117b9565b6106ac6101c087016101a088016117ed565b6106bc608088016060890161160d565b346106cf6101608a016101408b016117b9565b6106e16101808b016101608c016117b9565b8a6000013560008073ffffffffffffffffffffffffffffffffffffffff168d60e0016020810190610712919061160d565b73ffffffffffffffffffffffffffffffffffffffff16148061073157508a5b610c7b565b6000826107e45761074f6101208601610100870161160d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116906370a0823190602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df91906117a0565b6107e6565b475b90506107f28282611839565b9350610811602086013561080c60c0880160a0890161184c565b611177565b84101561084a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088e61085d60e0870160c0880161160d565b61086f6101208801610100890161160d565b61087f60a0890160808a0161184c565b61ffff1688602001358861119e565b935082156109455760006108a8606087016040880161160d565b73ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146108ff576040519150601f19603f3d011682016040523d82523d6000602084013e610904565b606091505b505090508061093f576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610988565b610988610958606087016040880161160d565b8561096b61012089016101008a0161160d565b73ffffffffffffffffffffffffffffffffffffffff169190611252565b61099a6101208601610100870161160d565b73ffffffffffffffffffffffffffffffffffffffff166109c1610100870160e0880161160d565b73ffffffffffffffffffffffffffffffffffffffff166109e760e0880160c0890161160d565b60408051893581526020810189905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261059e9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610512565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610acb9190611894565b6000604051808303816000865af19150503d8060008114610b08576040519150601f19603f3d011682016040523d82523d6000602084013e610b0d565b606091505b5091509150818015610b37575080511580610b37575080806020019051810190610b3791906118b0565b8015610b59575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610bc4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166112a89092919063ffffffff16565b9050805160001480610be5575080806020019051810190610be591906118b0565b610c76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b8860ff16600103610da9578715610d34576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015610d1657600080fd5b505af1158015610d2a573d6000803e3d6000fd5b505050505061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610cfd565b8860ff16600203610ee9578715610e74576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015610e49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b5061116c565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401610e2b565b8860ff1660030361108a578715610f67576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401610e2b565b8015610fe1576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401610e2b565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015611066573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e91906117a0565b8860ff1660040361113a5787156110cd576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401610cfd565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600061271061118683826118cd565b6111949061ffff16856118ef565b61033f9190611906565b60006107d08411156111e0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d06004820152602401610c6d565b600082848111156111f2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611228576064603284020461122b565b60005b9050808303838214611243576112438a8a84846112bf565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610c769084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610512565b60606112b78484600085611387565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606082471015611419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610c6d565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516114429190611894565b60006040518083038185875af1925050503d806000811461147f576040519150601f19603f3d011682016040523d82523d6000602084013e611484565b606091505b5091509150611495878383876114a0565b979650505050505050565b6060831561153657825160000361152f5773ffffffffffffffffffffffffffffffffffffffff85163b61152f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c6d565b50816112b7565b6112b7838381511561154b5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6d9190611941565b60006101c0828403121561159257600080fd5b50919050565b6000806101e083850312156115ac57600080fd5b6115b6848461157f565b91506101c083013567ffffffffffffffff8111156115d357600080fd5b8301604081860312156115e557600080fd5b809150509250929050565b60006101c0828403121561160357600080fd5b61033f838361157f565b60006020828403121561161f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461164357600080fd5b9392505050565b60006020828403121561165c57600080fd5b813565ffffffffffff8116811461164357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126116a757600080fd5b83018035915067ffffffffffffffff8211156116c257600080fd5b6020019150368190038213156116d757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156117b257600080fd5b5051919050565b6000602082840312156117cb57600080fd5b813560ff8116811461164357600080fd5b80151581146117ea57600080fd5b50565b6000602082840312156117ff57600080fd5b8135611643816117dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156103425761034261180a565b60006020828403121561185e57600080fd5b813561ffff8116811461164357600080fd5b60005b8381101561188b578181015183820152602001611873565b50506000910152565b600082516118a6818460208701611870565b9190910192915050565b6000602082840312156118c257600080fd5b8151611643816117dc565b61ffff8281168282160390808211156118e8576118e861180a565b5092915050565b80820281158282048414176103425761034261180a565b60008261193c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6020815260008251806020840152611960816040850160208701611870565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202b55d2f11aa7f1395a3e9c79ad5594ecdb6d8158214c767aed2d3da3a5500d1264736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, @@ -261,6 +357,11 @@ { "notice": "The swap fee is over the maximum allowed" } + ], + "PermitForEthToken()": [ + { + "notice": "A function expecting a permit was used when the input token is ETH" + } ] }, "kind": "user", diff --git a/packages/hardhat/deployments/optimism/Stargate.json b/packages/hardhat/deployments/optimism/Stargate.json index b366739d..9321acce 100644 --- a/packages/hardhat/deployments/optimism/Stargate.json +++ b/packages/hardhat/deployments/optimism/Stargate.json @@ -1,5 +1,5 @@ { - "address": "0x8A6e0BcC9D400c4fF243DA0D94c615504e821279", + "address": "0x7D03B60D0a8B854d688DcbEE6a08A8f7A80c0a1e", "abi": [ { "inputs": [ @@ -124,6 +124,76 @@ "stateMutability": "payable", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint160", + "name": "amountIn", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "amountOutExpected", + "type": "uint160" + }, + { + "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": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "srcPoolId", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "dstPoolId", + "type": "uint8" + } + ], + "internalType": "struct IStargate.JumpTokenParams", + "name": "params", + "type": "tuple" + } + ], + "name": "stargateJumpToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -206,34 +276,34 @@ "type": "tuple" } ], - "name": "stargateJumpToken", + "name": "stargateJumpTokenPermit", "outputs": [], "stateMutability": "payable", "type": "function" } ], - "transactionHash": "0x47509b8c40db62db5677e3f06d2133f6e113d3c8f340816a3590c5a3feba51c4", + "transactionHash": "0x77c76c28e110a4adbfdc8dcfde16cf1f6933725d87ba093c057e960d0ae0d8bb", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x8A6e0BcC9D400c4fF243DA0D94c615504e821279", - "transactionIndex": 4, - "gasUsed": "1184682", + "contractAddress": "0x7D03B60D0a8B854d688DcbEE6a08A8f7A80c0a1e", + "transactionIndex": 1, + "gasUsed": "1254228", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xb76c05a754138773010343005fcc972445be8fa4ec564a88e0ebf6bebfb2b9dc", - "transactionHash": "0x47509b8c40db62db5677e3f06d2133f6e113d3c8f340816a3590c5a3feba51c4", + "blockHash": "0x4b8d3e62ba6405fe9f45c97a96a5d3c2ecb79b4288d18d2eb4ee8e56a4c3ed5b", + "transactionHash": "0x77c76c28e110a4adbfdc8dcfde16cf1f6933725d87ba093c057e960d0ae0d8bb", "logs": [], - "blockNumber": 111055277, - "cumulativeGasUsed": "1939914", + "blockNumber": 111825992, + "cumulativeGasUsed": "1301141", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpNativeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"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\":\"stargateJumpToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Stargate.sol\":\"Stargate\"},\"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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract Stargate is IStargate {\\n using SafeERC20 for IERC20;\\n\\n function stargateJumpToken(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.token,\\n amount: 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 // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n uint160(params.amountIn),\\n params.token\\n );\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.token,\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n // NOTE: This lookup is spending 319 gas\\n IStargateRouter stargateRouter = IStargateRouter(\\n LibWarp.state().stargateComposer.stargateRouter()\\n );\\n\\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\\n\\n unchecked {\\n stargateRouter.swap{value: msg.value}({\\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\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n address(0),\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n unchecked {\\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n}\\n\",\"keccak256\":\"0x384ff4fd006f55fd52c6532724722c9d8709db7760e8296c8a9447a19bd148f1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/IStargate.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\n\\ninterface IStargate is ILibStarVault {\\n error InsufficientEthValue();\\n\\n struct JumpTokenParams {\\n address token;\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n struct JumpNativeParams {\\n /**\\n * The amount in is passed to distinguish the amount to bridge from the fee\\n */\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n function stargateJumpToken(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\\n}\\n\",\"keccak256\":\"0x4464ecac16a3c449c8f7983ac21ba54a44ac02194baa590c480b6ffc1cddd478\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b5061148c806100206000396000f3fe6080604052600436106100295760003560e01c806329859a061461002e578063c2bee2af14610043575b600080fd5b61004161003c366004610fca565b610056565b005b610041610051366004611029565b610618565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100b760208a018a611067565b73ffffffffffffffffffffffffffffffffffffffff1681526020018860200160208101906100e59190611067565b73ffffffffffffffffffffffffffffffffffffffff16815260200161011060e08a0160c08b0161108b565b65ffffffffffff9081168252883516602091820152908252309082015260400161014060e0880160c0890161108b565b65ffffffffffff16905261015760208601866110b3565b6040518563ffffffff1660e01b8152600401610176949392919061111f565b600060405180830381600087803b15801561019057600080fd5b505af11580156101a4573d6000803e3d6000fd5b505050506101cf7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633306102006040870160208801611067565b61020d6020880188611067565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561028b57600080fd5b505af115801561029f573d6000803e3d6000fd5b50505050600061032d8360e00160208101906102bb9190611067565b6102c86020860186611067565b6102d860c0870160a088016111e1565b61ffff166102ec6040880160208901611067565b73ffffffffffffffffffffffffffffffffffffffff166103126040890160208a01611067565b73ffffffffffffffffffffffffffffffffffffffff16610905565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190611205565b905061041581836103f86020880188611067565b73ffffffffffffffffffffffffffffffffffffffff1691906109be565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc34610444610120880161010089016111e1565b61045661014089016101208a01611222565b6104686101608a016101408b01611222565b33888061047b60408e0160208f01611067565b73ffffffffffffffffffffffffffffffffffffffff16036104a260608e0160408f01611067565b73ffffffffffffffffffffffffffffffffffffffff16116104c4576000610534565b6105348a8d60200160208101906104db9190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d60400160208101906105059190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d608001602081019061052f91906111e1565b610aee565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508d60600160208101906105739190611067565b6040516020016105ae919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016105e09897969594939291906112b3565b6000604051808303818588803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050505050505050565b6106256020820182611067565b73ffffffffffffffffffffffffffffffffffffffff16341015610674576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106cf61068960e0840160c08501611067565b600061069b60a08601608087016111e1565b61ffff166106ac6020870187611067565b73ffffffffffffffffffffffffffffffffffffffff166103126020880188611067565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261071d6020860186611067565b73ffffffffffffffffffffffffffffffffffffffff16033403610747610100860160e087016111e1565b61075961012087016101008801611222565b61076b61014088016101208901611222565b33878061077b60208c018c611067565b73ffffffffffffffffffffffffffffffffffffffff16036107a260408c0160208d01611067565b73ffffffffffffffffffffffffffffffffffffffff16116107c4576000610823565b610823896107d560208d018d611067565b73ffffffffffffffffffffffffffffffffffffffff16036107fc60408d0160208e01611067565b73ffffffffffffffffffffffffffffffffffffffff160361052f60808d0160608e016111e1565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b60400160208101906108629190611067565b60405160200161089d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016108cf9897969594939291906112b3565b6000604051808303818588803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b50505050505050565b60006107d084111561094c576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561095e575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109945760646032840204610997565b60005b90508083038382146109af576109af8a8a8484610b1e565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610a4a8482610be6565b610ae8576040805173ffffffffffffffffffffffffffffffffffffffff8516602482015260006044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610ade908590610ca7565b610ae88482610ca7565b50505050565b6000612710610afd8382611391565b610b0b9061ffff16856113b3565b610b1591906113ca565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c109190611405565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611421565b8015610c9e575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610dbb9092919063ffffffff16565b9050805160001480610d2a575080806020019051810190610d2a9190611421565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610943565b505050565b6060610dca8484600085610dd2565b949350505050565b606082471015610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610943565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610e8d9190611405565b60006040518083038185875af1925050503d8060008114610eca576040519150601f19603f3d011682016040523d82523d6000602084013e610ecf565b606091505b5091509150610ee087838387610eeb565b979650505050505050565b60608315610f81578251600003610f7a5773ffffffffffffffffffffffffffffffffffffffff85163b610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b5081610dca565b610dca8383815115610f965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109439190611443565b600080828403610180811215610fdf57600080fd5b61016080821215610fef57600080fd5b849350830135905067ffffffffffffffff81111561100c57600080fd5b83016040818603121561101e57600080fd5b809150509250929050565b6000610140828403121561103c57600080fd5b50919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461106457600080fd5b50565b60006020828403121561107957600080fd5b813561108481611042565b9392505050565b60006020828403121561109d57600080fd5b813565ffffffffffff8116811461108457600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110e857600080fd5b83018035915067ffffffffffffffff82111561110357600080fd5b60200191503681900382131561111857600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156111f357600080fd5b813561ffff8116811461108457600080fd5b60006020828403121561121757600080fd5b815161108481611042565b60006020828403121561123457600080fd5b813560ff8116811461108457600080fd5b60005b83811015611260578181015183820152602001611248565b50506000910152565b60008151808452611281816020860160208601611245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c08401528451818401525060208401516101408301526040840151606061016084015261132c610180840182611269565b905082810360e08401526113408185611269565b838103610100850152600081529050602081019b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156113ac576113ac611362565b5092915050565b8082028115828204841417610b1857610b18611362565b600082611400577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251611417818460208701611245565b9190910192915050565b60006020828403121561143357600080fd5b8151801515811461108457600080fd5b602081526000610b15602083018461126956fea2646970667358221220fd4949e43a56ae6a92fdbb921568c2bc2a7013da24304d0b873ce9c5e7515c0264736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806329859a061461002e578063c2bee2af14610043575b600080fd5b61004161003c366004610fca565b610056565b005b610041610051366004611029565b610618565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100b760208a018a611067565b73ffffffffffffffffffffffffffffffffffffffff1681526020018860200160208101906100e59190611067565b73ffffffffffffffffffffffffffffffffffffffff16815260200161011060e08a0160c08b0161108b565b65ffffffffffff9081168252883516602091820152908252309082015260400161014060e0880160c0890161108b565b65ffffffffffff16905261015760208601866110b3565b6040518563ffffffff1660e01b8152600401610176949392919061111f565b600060405180830381600087803b15801561019057600080fd5b505af11580156101a4573d6000803e3d6000fd5b505050506101cf7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633306102006040870160208801611067565b61020d6020880188611067565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b15801561028b57600080fd5b505af115801561029f573d6000803e3d6000fd5b50505050600061032d8360e00160208101906102bb9190611067565b6102c86020860186611067565b6102d860c0870160a088016111e1565b61ffff166102ec6040880160208901611067565b73ffffffffffffffffffffffffffffffffffffffff166103126040890160208a01611067565b73ffffffffffffffffffffffffffffffffffffffff16610905565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e49190611205565b905061041581836103f86020880188611067565b73ffffffffffffffffffffffffffffffffffffffff1691906109be565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc34610444610120880161010089016111e1565b61045661014089016101208a01611222565b6104686101608a016101408b01611222565b33888061047b60408e0160208f01611067565b73ffffffffffffffffffffffffffffffffffffffff16036104a260608e0160408f01611067565b73ffffffffffffffffffffffffffffffffffffffff16116104c4576000610534565b6105348a8d60200160208101906104db9190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d60400160208101906105059190611067565b73ffffffffffffffffffffffffffffffffffffffff16038d608001602081019061052f91906111e1565b610aee565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508d60600160208101906105739190611067565b6040516020016105ae919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016105e09897969594939291906112b3565b6000604051808303818588803b1580156105f957600080fd5b505af115801561060d573d6000803e3d6000fd5b505050505050505050565b6106256020820182611067565b73ffffffffffffffffffffffffffffffffffffffff16341015610674576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106cf61068960e0840160c08501611067565b600061069b60a08601608087016111e1565b61ffff166106ac6020870187611067565b73ffffffffffffffffffffffffffffffffffffffff166103126020880188611067565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261071d6020860186611067565b73ffffffffffffffffffffffffffffffffffffffff16033403610747610100860160e087016111e1565b61075961012087016101008801611222565b61076b61014088016101208901611222565b33878061077b60208c018c611067565b73ffffffffffffffffffffffffffffffffffffffff16036107a260408c0160208d01611067565b73ffffffffffffffffffffffffffffffffffffffff16116107c4576000610823565b610823896107d560208d018d611067565b73ffffffffffffffffffffffffffffffffffffffff16036107fc60408d0160208e01611067565b73ffffffffffffffffffffffffffffffffffffffff160361052f60808d0160608e016111e1565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b60400160208101906108629190611067565b60405160200161089d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016108cf9897969594939291906112b3565b6000604051808303818588803b1580156108e857600080fd5b505af11580156108fc573d6000803e3d6000fd5b50505050505050565b60006107d084111561094c576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561095e575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109945760646032840204610997565b60005b90508083038382146109af576109af8a8a8484610b1e565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610a4a8482610be6565b610ae8576040805173ffffffffffffffffffffffffffffffffffffffff8516602482015260006044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610ade908590610ca7565b610ae88482610ca7565b50505050565b6000612710610afd8382611391565b610b0b9061ffff16856113b3565b610b1591906113ca565b90505b92915050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c109190611405565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190611421565b8015610c9e575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610dbb9092919063ffffffff16565b9050805160001480610d2a575080806020019051810190610d2a9190611421565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610943565b505050565b6060610dca8484600085610dd2565b949350505050565b606082471015610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610943565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610e8d9190611405565b60006040518083038185875af1925050503d8060008114610eca576040519150601f19603f3d011682016040523d82523d6000602084013e610ecf565b606091505b5091509150610ee087838387610eeb565b979650505050505050565b60608315610f81578251600003610f7a5773ffffffffffffffffffffffffffffffffffffffff85163b610f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b5081610dca565b610dca8383815115610f965781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109439190611443565b600080828403610180811215610fdf57600080fd5b61016080821215610fef57600080fd5b849350830135905067ffffffffffffffff81111561100c57600080fd5b83016040818603121561101e57600080fd5b809150509250929050565b6000610140828403121561103c57600080fd5b50919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461106457600080fd5b50565b60006020828403121561107957600080fd5b813561108481611042565b9392505050565b60006020828403121561109d57600080fd5b813565ffffffffffff8116811461108457600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110e857600080fd5b83018035915067ffffffffffffffff82111561110357600080fd5b60200191503681900382131561111857600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156111f357600080fd5b813561ffff8116811461108457600080fd5b60006020828403121561121757600080fd5b815161108481611042565b60006020828403121561123457600080fd5b813560ff8116811461108457600080fd5b60005b83811015611260578181015183820152602001611248565b50506000910152565b60008151808452611281816020860160208601611245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c08401528451818401525060208401516101408301526040840151606061016084015261132c610180840182611269565b905082810360e08401526113408185611269565b838103610100850152600081529050602081019b9a5050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156113ac576113ac611362565b5092915050565b8082028115828204841417610b1857610b18611362565b600082611400577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251611417818460208701611245565b9190910192915050565b60006020828403121561143357600080fd5b8151801515811461108457600080fd5b602081526000610b15602083018461126956fea2646970667358221220fd4949e43a56ae6a92fdbb921568c2bc2a7013da24304d0b873ce9c5e7515c0264736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpNativeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"stargateJumpToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint160\",\"name\":\"amountIn\",\"type\":\"uint160\"},{\"internalType\":\"uint160\",\"name\":\"amountOutExpected\",\"type\":\"uint160\"},{\"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\":\"uint16\",\"name\":\"dstChainId\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"srcPoolId\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"dstPoolId\",\"type\":\"uint8\"}],\"internalType\":\"struct IStargate.JumpTokenParams\",\"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\":\"stargateJumpTokenPermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Stargate.sol\":\"Stargate\"},\"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/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract Stargate is IStargate {\\n using SafeERC20 for IERC20;\\n\\n /**\\n * Jump tokens with Stargate with input tokens already moved to this contract\\n */\\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.token,\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n // NOTE: This lookup is spending 319 gas\\n IStargateRouter stargateRouter = IStargateRouter(\\n LibWarp.state().stargateComposer.stargateRouter()\\n );\\n\\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\\n\\n unchecked {\\n stargateRouter.swap{value: msg.value}({\\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\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n\\n function stargateJumpTokenPermit(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.token,\\n amount: 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 // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n uint160(params.amountIn),\\n params.token\\n );\\n\\n stargateJumpTokenInternal(params);\\n }\\n\\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\\n // Transfer tokens from the sender to this contract\\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\\n\\n stargateJumpTokenInternal(params);\\n }\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\\n // is never charged\\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n address(0),\\n params.feeBps,\\n params.amountIn,\\n params.amountIn\\n );\\n\\n unchecked {\\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n _refundAddress: payable(msg.sender),\\n _amountLD: amountIn,\\n // Apply slippage to the amountOutExpected after fees\\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\\n ? LibWarp.applySlippage(\\n params.amountOutExpected - (params.amountIn - amountIn),\\n params.slippageBps\\n )\\n : 0,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(params.recipient),\\n _payload: ''\\n });\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6abe4954877eed5b5a9c473441ac11e6f505d6cedc5c1d9489960227c5fb6f84\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/IStargate.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\n\\ninterface IStargate is ILibStarVault {\\n error InsufficientEthValue();\\n\\n struct JumpTokenParams {\\n address token;\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n struct JumpNativeParams {\\n /**\\n * The amount in is passed to distinguish the amount to bridge from the fee\\n */\\n uint160 amountIn;\\n /**\\n * The amount the user was quoted. Used to calculate the minimum acceptable\\n * amount of tokens to receive.\\n */\\n uint160 amountOutExpected;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n uint16 dstChainId;\\n uint8 srcPoolId;\\n uint8 dstPoolId;\\n }\\n\\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\\n\\n function stargateJumpTokenPermit(\\n JumpTokenParams calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n\\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\\n}\\n\",\"keccak256\":\"0xb35bd721e5ab9f7cd120a61bdafd807dcebd1cf71f5189662697f47a1f10986c\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506115d1806100206000396000f3fe6080604052600436106100345760003560e01c80638be9f27914610039578063ba2466d41461004e578063c2bee2af14610061575b600080fd5b61004c610047366004611102565b610074565b005b61004c61005c36600461115a565b6102ce565b61004c61006f366004611177565b610330565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100d560208a018a6111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200188602001602081019061010391906111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200161012e60e08a0160c08b016111d0565b65ffffffffffff9081168252883516602091820152908252309082015260400161015e60e0880160c089016111d0565b65ffffffffffff16905261017560208601866111f8565b6040518563ffffffff1660e01b81526004016101949493929190611264565b600060405180830381600087803b1580156101ae57600080fd5b505af11580156101c2573d6000803e3d6000fd5b505050506101ed7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333061021e60408701602088016111ac565b61022b60208801886111ac565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102a957600080fd5b505af11580156102bd573d6000803e3d6000fd5b505050506102ca8261063d565b5050565b61032433306102e360408501602086016111ac565b73ffffffffffffffffffffffffffffffffffffffff1661030660208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff16929190610986565b61032d8161063d565b50565b61033d60208201826111ac565b73ffffffffffffffffffffffffffffffffffffffff1634101561038c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104026103a160e0840160c085016111ac565b60006103b360a0860160808701611326565b61ffff166103c460208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760208801886111ac565b73ffffffffffffffffffffffffffffffffffffffff16610a68565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261045060208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff1603340361047a610100860160e08701611326565b61048c6101208701610100880161134a565b61049e6101408801610120890161134a565b3387806104ae60208c018c6111ac565b73ffffffffffffffffffffffffffffffffffffffff16036104d560408c0160208d016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116104f757600061055b565b61055b8961050860208d018d6111ac565b73ffffffffffffffffffffffffffffffffffffffff160361052f60408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660808d0160608e01611326565b610b21565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b604001602081019061059a91906111ac565b6040516020016105d5919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016106079897969594939291906113db565b6000604051808303818588803b15801561062057600080fd5b505af1158015610634573d6000803e3d6000fd5b50505050505050565b60006106aa610653610100840160e085016111ac565b61066060208501856111ac565b61067060c0860160a08701611326565b61ffff1661068460408701602088016111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760408801602089016111ac565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610761919061148a565b9050610792818361077560208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff169190610b51565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc346107c161012087016101008801611326565b6107d36101408801610120890161134a565b6107e561016089016101408a0161134a565b3388806107f860408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361081f60608d0160408e016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116108415760006108a3565b6108a38a61085560408e0160208f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361087c60608e0160408f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660a08e0160808f01611326565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60600160208101906108e291906111ac565b60405160200161091d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b815260040161094f9897969594939291906113db565b6000604051808303818588803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a629085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610c3d565b50505050565b60006107d0841115610aaf576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610ac1575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610af75760646032840204610afa565b60005b9050808303838214610b1257610b128a8a8484610d51565b50505090910395945050505050565b6000612710610b3083826114d6565b610b3e9061ffff16856114f8565b610b48919061150f565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610bdd8482610e19565b610a625760405173ffffffffffffffffffffffffffffffffffffffff8416602482015260006044820152610c379085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109e0565b610a6284825b6000610c9f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610eda9092919063ffffffff16565b9050805160001480610cc0575080806020019051810190610cc0919061154a565b610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa6565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e43919061156c565b6000604051808303816000865af19150503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5091509150818015610eaf575080511580610eaf575080806020019051810190610eaf919061154a565b8015610ed1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060610ee98484600085610ef1565b949350505050565b606082471015610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fac919061156c565b60006040518083038185875af1925050503d8060008114610fe9576040519150601f19603f3d011682016040523d82523d6000602084013e610fee565b606091505b5091509150610fff8783838761100a565b979650505050505050565b606083156110a05782516000036110995773ffffffffffffffffffffffffffffffffffffffff85163b611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa6565b5081610ee9565b610ee983838151156110b55781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa69190611588565b600061016082840312156110fc57600080fd5b50919050565b600080610180838503121561111657600080fd5b61112084846110e9565b915061016083013567ffffffffffffffff81111561113d57600080fd5b83016040818603121561114f57600080fd5b809150509250929050565b6000610160828403121561116d57600080fd5b610b4883836110e9565b600061014082840312156110fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461032d57600080fd5b6000602082840312156111be57600080fd5b81356111c98161118a565b9392505050565b6000602082840312156111e257600080fd5b813565ffffffffffff811681146111c957600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261122d57600080fd5b83018035915067ffffffffffffffff82111561124857600080fd5b60200191503681900382131561125d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60006020828403121561133857600080fd5b813561ffff811681146111c957600080fd5b60006020828403121561135c57600080fd5b813560ff811681146111c957600080fd5b60005b83811015611388578181015183820152602001611370565b50506000910152565b600081518084526113a981602086016020860161136d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c084015284518184015250602084015161014083015260408401516060610160840152611454610180840182611391565b905082810360e08401526114688185611391565b838103610100850152600081529050602081019b9a5050505050505050505050565b60006020828403121561149c57600080fd5b81516111c98161118a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156114f1576114f16114a7565b5092915050565b8082028115828204841417610b4b57610b4b6114a7565b600082611545577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561155c57600080fd5b815180151581146111c957600080fd5b6000825161157e81846020870161136d565b9190910192915050565b602081526000610b48602083018461139156fea26469706673582212208328d8149ca8eb632152123f06714fc50d6667b0823eba29b328ace315d4e37464736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c80638be9f27914610039578063ba2466d41461004e578063c2bee2af14610061575b600080fd5b61004c610047366004611102565b610074565b005b61004c61005c36600461115a565b6102ce565b61004c61006f366004611177565b610330565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915273ffffffffffffffffffffffffffffffffffffffff90911690632b67b5709033908060608101806100d560208a018a6111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200188602001602081019061010391906111ac565b73ffffffffffffffffffffffffffffffffffffffff16815260200161012e60e08a0160c08b016111d0565b65ffffffffffff9081168252883516602091820152908252309082015260400161015e60e0880160c089016111d0565b65ffffffffffff16905261017560208601866111f8565b6040518563ffffffff1660e01b81526004016101949493929190611264565b600060405180830381600087803b1580156101ae57600080fd5b505af11580156101c2573d6000803e3d6000fd5b505050506101ed7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c78516333061021e60408701602088016111ac565b61022b60208801886111ac565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102a957600080fd5b505af11580156102bd573d6000803e3d6000fd5b505050506102ca8261063d565b5050565b61032433306102e360408501602086016111ac565b73ffffffffffffffffffffffffffffffffffffffff1661030660208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff16929190610986565b61032d8161063d565b50565b61033d60208201826111ac565b73ffffffffffffffffffffffffffffffffffffffff1634101561038c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104026103a160e0840160c085016111ac565b60006103b360a0860160808701611326565b61ffff166103c460208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760208801886111ac565b73ffffffffffffffffffffffffffffffffffffffff16610a68565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125490915073ffffffffffffffffffffffffffffffffffffffff16639fbf10fc8261045060208601866111ac565b73ffffffffffffffffffffffffffffffffffffffff1603340361047a610100860160e08701611326565b61048c6101208701610100880161134a565b61049e6101408801610120890161134a565b3387806104ae60208c018c6111ac565b73ffffffffffffffffffffffffffffffffffffffff16036104d560408c0160208d016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116104f757600061055b565b61055b8961050860208d018d6111ac565b73ffffffffffffffffffffffffffffffffffffffff160361052f60408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660808d0160608e01611326565b610b21565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508b604001602081019061059a91906111ac565b6040516020016105d5919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b81526004016106079897969594939291906113db565b6000604051808303818588803b15801561062057600080fd5b505af1158015610634573d6000803e3d6000fd5b50505050505050565b60006106aa610653610100840160e085016111ac565b61066060208501856111ac565b61067060c0860160a08701611326565b61ffff1661068460408701602088016111ac565b73ffffffffffffffffffffffffffffffffffffffff166103e760408801602089016111ac565b905060007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610761919061148a565b9050610792818361077560208701876111ac565b73ffffffffffffffffffffffffffffffffffffffff169190610b51565b73ffffffffffffffffffffffffffffffffffffffff8116639fbf10fc346107c161012087016101008801611326565b6107d36101408801610120890161134a565b6107e561016089016101408a0161134a565b3388806107f860408d0160208e016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361081f60608d0160408e016111ac565b73ffffffffffffffffffffffffffffffffffffffff16116108415760006108a3565b6108a38a61085560408e0160208f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361087c60608e0160408f016111ac565b73ffffffffffffffffffffffffffffffffffffffff160361055660a08e0160808f01611326565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60600160208101906108e291906111ac565b60405160200161091d919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b815260040161094f9897969594939291906113db565b6000604051808303818588803b15801561096857600080fd5b505af115801561097c573d6000803e3d6000fd5b5050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a629085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610c3d565b50505050565b60006107d0841115610aaf576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610ac1575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610af75760646032840204610afa565b60005b9050808303838214610b1257610b128a8a8484610d51565b50505090910395945050505050565b6000612710610b3083826114d6565b610b3e9061ffff16856114f8565b610b48919061150f565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052610bdd8482610e19565b610a625760405173ffffffffffffffffffffffffffffffffffffffff8416602482015260006044820152610c379085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109e0565b610a6284825b6000610c9f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610eda9092919063ffffffff16565b9050805160001480610cc0575080806020019051810190610cc0919061154a565b610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa6565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610e43919061156c565b6000604051808303816000865af19150503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5091509150818015610eaf575080511580610eaf575080806020019051810190610eaf919061154a565b8015610ed1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060610ee98484600085610ef1565b949350505050565b606082471015610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fac919061156c565b60006040518083038185875af1925050503d8060008114610fe9576040519150601f19603f3d011682016040523d82523d6000602084013e610fee565b606091505b5091509150610fff8783838761100a565b979650505050505050565b606083156110a05782516000036110995773ffffffffffffffffffffffffffffffffffffffff85163b611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa6565b5081610ee9565b610ee983838151156110b55781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa69190611588565b600061016082840312156110fc57600080fd5b50919050565b600080610180838503121561111657600080fd5b61112084846110e9565b915061016083013567ffffffffffffffff81111561113d57600080fd5b83016040818603121561114f57600080fd5b809150509250929050565b6000610160828403121561116d57600080fd5b610b4883836110e9565b600061014082840312156110fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461032d57600080fd5b6000602082840312156111be57600080fd5b81356111c98161118a565b9392505050565b6000602082840312156111e257600080fd5b813565ffffffffffff811681146111c957600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261122d57600080fd5b83018035915067ffffffffffffffff82111561124857600080fd5b60200191503681900382131561125d57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60006020828403121561133857600080fd5b813561ffff811681146111c957600080fd5b60006020828403121561135c57600080fd5b813560ff811681146111c957600080fd5b60005b83811015611388578181015183820152602001611370565b50506000910152565b600081518084526113a981602086016020860161136d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835260ff8a16602084015260ff8916604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c084015284518184015250602084015161014083015260408401516060610160840152611454610180840182611391565b905082810360e08401526114688185611391565b838103610100850152600081529050602081019b9a5050505050505050505050565b60006020828403121561149c57600080fd5b81516111c98161118a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61ffff8281168282160390808211156114f1576114f16114a7565b5092915050565b8082028115828204841417610b4b57610b4b6114a7565b600082611545577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561155c57600080fd5b815180151581146111c957600080fd5b6000825161157e81846020870161136d565b9190910192915050565b602081526000610b48602083018461139156fea26469706673582212208328d8149ca8eb632152123f06714fc50d6667b0823eba29b328ace315d4e37464736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/UniV2LikeFacet.json b/packages/hardhat/deployments/optimism/UniV2LikeFacet.json index 9a00a649..79c090d9 100644 --- a/packages/hardhat/deployments/optimism/UniV2LikeFacet.json +++ b/packages/hardhat/deployments/optimism/UniV2LikeFacet.json @@ -1,5 +1,5 @@ { - "address": "0x23DbabD503fE9Fe046065b735377458957F73f18", + "address": "0xeeaA06C06D807A42D98f5202BCDeBd39C44F192a", "abi": [ { "inputs": [], @@ -116,6 +116,77 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV2LikeExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -193,7 +264,83 @@ "type": "tuple" } ], - "name": "uniswapV2LikeExactInput", + "name": "uniswapV2LikeExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV2LikeExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -286,7 +433,7 @@ "type": "tuple" } ], - "name": "uniswapV2LikeExactInputSingle", + "name": "uniswapV2LikeExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -294,32 +441,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0xb221b3b10f874165ebdbc19c188e02f0e97c001bb2c7bb683dedadb87467ea92", + "transactionHash": "0x1eee4d6e25a6166e6d2ae917c9186bf318cf70199bd6d41b1d565faa4b38b3bb", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x23DbabD503fE9Fe046065b735377458957F73f18", - "transactionIndex": 2, - "gasUsed": "2101579", + "contractAddress": "0xeeaA06C06D807A42D98f5202BCDeBd39C44F192a", + "transactionIndex": 7, + "gasUsed": "2340469", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcf712e027276ffa80e99e43123b9b38a2c8be07d6dda51d2751e281be9b00725", - "transactionHash": "0xb221b3b10f874165ebdbc19c188e02f0e97c001bb2c7bb683dedadb87467ea92", + "blockHash": "0xce55862c33ccbe5ea9abb4453658ce8aaadf3baf4a12f0cc760e6028cbd7f2c3", + "transactionHash": "0x1eee4d6e25a6166e6d2ae917c9186bf318cf70199bd6d41b1d565faa4b38b3bb", "logs": [], - "blockNumber": 111055241, - "cumulativeGasUsed": "2321529", + "blockNumber": 111825941, + "cumulativeGasUsed": "3887041", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 9, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokens[0],\\n isToEth ? address(0) : params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x4d807156203d016fd7fe1ff2dd503972c0f07d9d8f1b0794aca4459c1ea03b7a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Like is ILibStarVault, ILibWarp {\\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\":\"0x80c9be72cf89c5673f0acfb44d672ae65e86062906042a31007a9737c9e1a3db\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612542806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611e34565b610066565b60405190815260200160405180910390f35b610041610061366004612036565b6109e7565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101949190612176565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb6121fd565b0497505061030189602001518a60a00151611569565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611599565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61222c565b6040518563ffffffff1660e01b81526004016104db9493929190612298565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b505050506101008a01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190612176565b90508481108061076b57506107688986612389565b81105b156107a2576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c48b60c001518c61010001518d6080015161ffff168e602001518d61162b565b985085156108f35787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108ad576040519150601f19603f3d011682016040523d82523d6000602084013e6108b2565b606091505b50509050806108ed576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610927565b6109278b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b85610937578a610100015161093a565b60005b73ffffffffffffffffffffffffffffffffffffffff168761095f578b60e00151610962565b60005b73ffffffffffffffffffffffffffffffffffffffff168c60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38e600001518d6040516109d1929190918252602082015260400190565b60405180910390a4505050505050505092915050565b60008260c0015165ffffffffffff16421115610a2f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1092916000918291908290610a7557610a7561239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610ac657610ac661239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610ba4578761010001518481518110610b0557610b0561239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9f9190612176565b610ba6565b475b90506000610bc889604001518a600001518b61010001518c61012001516116e4565b9050610bdc89602001518a60800151611569565b8160018351610beb91906123cb565b81518110610bfb57610bfb61239c565b60200260200101511015610c3b576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610d725788513414610c7b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b5050505050610d6d896101200151600081518110610d1b57610d1b61239c565b60200260200101518a600001518b6101000151600081518110610d4057610d4061239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b610fc7565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610de157610de161239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610e87919061222c565b6040518563ffffffff1660e01b8152600401610ea69493929190612298565b600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610f1557610f1561239c565b60200260200101518c600001518d6101000151600081518110610f3a57610f3a61239c565b60200260200101516040518563ffffffff1660e01b8152600401610f94949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610fae57600080fd5b505af1158015610fc2573d6000803e3d6000fd5b505050505b60005b858110156111d0576000610fdf826001612389565b905060008b61010001518281518110610ffa57610ffa61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c6101000151848151811061102f5761102f61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061105957600061105c565b60015b9050600060028d61010001515161107391906123cb565b841061107f573061109f565b8c610120015183815181106110965761109661239c565b60200260200101515b90508c610120015184815181106110b8576110b861239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836110ff578685815181106110f2576110f261239c565b6020026020010151611102565b60005b8461110e576000611129565b8786815181106111205761112061239c565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156111a957600080fd5b505af11580156111bd573d6000803e3d6000fd5b505060019095019450610fca9350505050565b50600089610100015186815181106111ea576111ea61239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190612176565b90508281108061129c57506112998884612389565b81105b156112d3576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113278a60e001518b610100015188815181106112f2576112f261239c565b60200260200101518c60a0015161ffff168d60200151868b8151811061131a5761131a61239c565b602002602001015161162b565b975083156114565786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611410576040519150601f19603f3d011682016040523d82523d6000602084013e611415565b606091505b5050905080611450576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611476565b6114768a60600151898c61010001518981518110610d4057610d4061239c565b8361149f5789610100015186815181106114925761149261239c565b60200260200101516114a2565b60005b73ffffffffffffffffffffffffffffffffffffffff16856114e2578a61010001516000815181106114d5576114d561239c565b60200260200101516114e5565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60e0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c604051611554929190918252602082015260400190565b60405180910390a45050505050505092915050565b600061271061157883826123de565b6115869061ffff1685612400565b6115909190612417565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611626908490611919565b505050565b60006107d0841115611672576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611684575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116ba57606460328402046116bd565b60005b90508083038382146116d5576116d58a8a8484611a28565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561170457611704611cff565b60405190808252806020026020018201604052801561172d578160200160208202803683370190505b50915084826000815181106117445761174461239c565b60200260200101818152505060005b8181101561190f57600085828151811061176f5761176f61239c565b602002602001015190506000868360016117899190612389565b815181106117995761179961239c565b6020026020010151905060008984815181106117b7576117b761239c565b60200260200101516127106117cc91906123de565b61ffff1690506000808886815181106117e7576117e761239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185d91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156118b857905b828b0282612710020181848d0202816118d3576118d36121fd565b049a508a886118e3886001612389565b815181106118f3576118f361239c565b6020908102919091010152505060019093019250611753915050565b5050949350505050565b600061197b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611af09092919063ffffffff16565b905080516000148061199c57508080602001905181019061199c9190612452565b611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611669565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611aff8484600085611b07565b949350505050565b606082471015611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611669565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bc2919061249f565b60006040518083038185875af1925050503d8060008114611bff576040519150601f19603f3d011682016040523d82523d6000602084013e611c04565b606091505b5091509150611c1587838387611c20565b979650505050505050565b60608315611cb6578251600003611caf5773ffffffffffffffffffffffffffffffffffffffff85163b611caf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611669565b5081611aff565b611aff8383815115611ccb5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166991906124bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611d5257611d52611cff565b60405290565b604051610140810167ffffffffffffffff81118282101715611d5257611d52611cff565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc357611dc3611cff565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611def57600080fd5b919050565b803561ffff81168114611def57600080fd5b803565ffffffffffff81168114611def57600080fd5b600060408284031215611e2e57600080fd5b50919050565b600080828403610180811215611e4957600080fd5b61016080821215611e5957600080fd5b611e61611d2e565b91508435825260208501356020830152611e7d60408601611dcb565b6040830152611e8e60608601611dcb565b6060830152611e9f60808601611df4565b6080830152611eb060a08601611df4565b60a0830152611ec160c08601611dcb565b60c0830152611ed260e08601611dcb565b60e0830152610100611ee5818701611dcb565b90830152610120611ef7868201611df4565b90830152610140611f09868201611e06565b9083015290925083013567ffffffffffffffff811115611f2857600080fd5b611f3485828601611e1c565b9150509250929050565b600067ffffffffffffffff821115611f5857611f58611cff565b5060051b60200190565b600082601f830112611f7357600080fd5b81356020611f88611f8383611f3e565b611d7c565b82815260059290921b84018101918181019086841115611fa757600080fd5b8286015b84811015611fc957611fbc81611df4565b8352918301918301611fab565b509695505050505050565b600082601f830112611fe557600080fd5b81356020611ff5611f8383611f3e565b82815260059290921b8401810191818101908684111561201457600080fd5b8286015b84811015611fc95761202981611dcb565b8352918301918301612018565b6000806040838503121561204957600080fd5b823567ffffffffffffffff8082111561206157600080fd5b90840190610140828703121561207657600080fd5b61207e611d58565b823581526020830135602082015260408301358281111561209e57600080fd5b6120aa88828601611f62565b6040830152506120bc60608401611dcb565b60608201526120cd60808401611df4565b60808201526120de60a08401611df4565b60a08201526120ef60c08401611e06565b60c082015261210060e08401611dcb565b60e0820152610100808401358381111561211957600080fd5b61212589828701611fd4565b828401525050610120808401358381111561213f57600080fd5b61214b89828701611fd4565b82840152505080945050602085013591508082111561216957600080fd5b50611f3485828601611e1c565b60006020828403121561218857600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611def57600080fd5b6000806000606084860312156121c257600080fd5b6121cb8461218f565b92506121d96020850161218f565b9150604084015163ffffffff811681146121f257600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261226157600080fd5b83018035915067ffffffffffffffff82111561227c57600080fd5b60200191503681900382131561229157600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156115935761159361235a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b818103818111156115935761159361235a565b61ffff8281168282160390808211156123f9576123f961235a565b5092915050565b80820281158282048414176115935761159361235a565b60008261244d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561246457600080fd5b8151801515811461247457600080fd5b9392505050565b60005b8381101561249657818101518382015260200161247e565b50506000910152565b600082516124b181846020870161247b565b9190910192915050565b60208152600082518060208401526124da81604085016020870161247b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220200d00eba2c244bcc4394586e11bed52f1bde27d737f84e6823312ec945bdf2064736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611e34565b610066565b60405190815260200160405180910390f35b610041610061366004612036565b6109e7565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101949190612176565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb6121fd565b0497505061030189602001518a60a00151611569565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611599565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61222c565b6040518563ffffffff1660e01b81526004016104db9493929190612298565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b505050506101008a01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190612176565b90508481108061076b57506107688986612389565b81105b156107a2576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c48b60c001518c61010001518d6080015161ffff168e602001518d61162b565b985085156108f35787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108ad576040519150601f19603f3d011682016040523d82523d6000602084013e6108b2565b606091505b50509050806108ed576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610927565b6109278b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b85610937578a610100015161093a565b60005b73ffffffffffffffffffffffffffffffffffffffff168761095f578b60e00151610962565b60005b73ffffffffffffffffffffffffffffffffffffffff168c60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38e600001518d6040516109d1929190918252602082015260400190565b60405180910390a4505050505050505092915050565b60008260c0015165ffffffffffff16421115610a2f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1092916000918291908290610a7557610a7561239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610ac657610ac661239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610ba4578761010001518481518110610b0557610b0561239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9f9190612176565b610ba6565b475b90506000610bc889604001518a600001518b61010001518c61012001516116e4565b9050610bdc89602001518a60800151611569565b8160018351610beb91906123cb565b81518110610bfb57610bfb61239c565b60200260200101511015610c3b576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610d725788513414610c7b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610ce757600080fd5b505af1158015610cfb573d6000803e3d6000fd5b5050505050610d6d896101200151600081518110610d1b57610d1b61239c565b60200260200101518a600001518b6101000151600081518110610d4057610d4061239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115999092919063ffffffff16565b610fc7565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610de157610de161239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610e87919061222c565b6040518563ffffffff1660e01b8152600401610ea69493929190612298565b600060405180830381600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610f1557610f1561239c565b60200260200101518c600001518d6101000151600081518110610f3a57610f3a61239c565b60200260200101516040518563ffffffff1660e01b8152600401610f94949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610fae57600080fd5b505af1158015610fc2573d6000803e3d6000fd5b505050505b60005b858110156111d0576000610fdf826001612389565b905060008b61010001518281518110610ffa57610ffa61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c6101000151848151811061102f5761102f61239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061105957600061105c565b60015b9050600060028d61010001515161107391906123cb565b841061107f573061109f565b8c610120015183815181106110965761109661239c565b60200260200101515b90508c610120015184815181106110b8576110b861239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836110ff578685815181106110f2576110f261239c565b6020026020010151611102565b60005b8461110e576000611129565b8786815181106111205761112061239c565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156111a957600080fd5b505af11580156111bd573d6000803e3d6000fd5b505060019095019450610fca9350505050565b50600089610100015186815181106111ea576111ea61239c565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611260573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112849190612176565b90508281108061129c57506112998884612389565b81105b156112d3576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113278a60e001518b610100015188815181106112f2576112f261239c565b60200260200101518c60a0015161ffff168d60200151868b8151811061131a5761131a61239c565b602002602001015161162b565b975083156114565786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d8060008114611410576040519150601f19603f3d011682016040523d82523d6000602084013e611415565b606091505b5050905080611450576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611476565b6114768a60600151898c61010001518981518110610d4057610d4061239c565b8361149f5789610100015186815181106114925761149261239c565b60200260200101516114a2565b60005b73ffffffffffffffffffffffffffffffffffffffff16856114e2578a61010001516000815181106114d5576114d561239c565b60200260200101516114e5565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60e0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518c604051611554929190918252602082015260400190565b60405180910390a45050505050505092915050565b600061271061157883826123de565b6115869061ffff1685612400565b6115909190612417565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611626908490611919565b505050565b60006107d0841115611672576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611684575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116ba57606460328402046116bd565b60005b90508083038382146116d5576116d58a8a8484611a28565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561170457611704611cff565b60405190808252806020026020018201604052801561172d578160200160208202803683370190505b50915084826000815181106117445761174461239c565b60200260200101818152505060005b8181101561190f57600085828151811061176f5761176f61239c565b602002602001015190506000868360016117899190612389565b815181106117995761179961239c565b6020026020010151905060008984815181106117b7576117b761239c565b60200260200101516127106117cc91906123de565b61ffff1690506000808886815181106117e7576117e761239c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185d91906121ad565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156118b857905b828b0282612710020181848d0202816118d3576118d36121fd565b049a508a886118e3886001612389565b815181106118f3576118f361239c565b6020908102919091010152505060019093019250611753915050565b5050949350505050565b600061197b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611af09092919063ffffffff16565b905080516000148061199c57508080602001905181019061199c9190612452565b611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611669565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060611aff8484600085611b07565b949350505050565b606082471015611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611669565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bc2919061249f565b60006040518083038185875af1925050503d8060008114611bff576040519150601f19603f3d011682016040523d82523d6000602084013e611c04565b606091505b5091509150611c1587838387611c20565b979650505050505050565b60608315611cb6578251600003611caf5773ffffffffffffffffffffffffffffffffffffffff85163b611caf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611669565b5081611aff565b611aff8383815115611ccb5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166991906124bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611d5257611d52611cff565b60405290565b604051610140810167ffffffffffffffff81118282101715611d5257611d52611cff565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc357611dc3611cff565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611def57600080fd5b919050565b803561ffff81168114611def57600080fd5b803565ffffffffffff81168114611def57600080fd5b600060408284031215611e2e57600080fd5b50919050565b600080828403610180811215611e4957600080fd5b61016080821215611e5957600080fd5b611e61611d2e565b91508435825260208501356020830152611e7d60408601611dcb565b6040830152611e8e60608601611dcb565b6060830152611e9f60808601611df4565b6080830152611eb060a08601611df4565b60a0830152611ec160c08601611dcb565b60c0830152611ed260e08601611dcb565b60e0830152610100611ee5818701611dcb565b90830152610120611ef7868201611df4565b90830152610140611f09868201611e06565b9083015290925083013567ffffffffffffffff811115611f2857600080fd5b611f3485828601611e1c565b9150509250929050565b600067ffffffffffffffff821115611f5857611f58611cff565b5060051b60200190565b600082601f830112611f7357600080fd5b81356020611f88611f8383611f3e565b611d7c565b82815260059290921b84018101918181019086841115611fa757600080fd5b8286015b84811015611fc957611fbc81611df4565b8352918301918301611fab565b509695505050505050565b600082601f830112611fe557600080fd5b81356020611ff5611f8383611f3e565b82815260059290921b8401810191818101908684111561201457600080fd5b8286015b84811015611fc95761202981611dcb565b8352918301918301612018565b6000806040838503121561204957600080fd5b823567ffffffffffffffff8082111561206157600080fd5b90840190610140828703121561207657600080fd5b61207e611d58565b823581526020830135602082015260408301358281111561209e57600080fd5b6120aa88828601611f62565b6040830152506120bc60608401611dcb565b60608201526120cd60808401611df4565b60808201526120de60a08401611df4565b60a08201526120ef60c08401611e06565b60c082015261210060e08401611dcb565b60e0820152610100808401358381111561211957600080fd5b61212589828701611fd4565b828401525050610120808401358381111561213f57600080fd5b61214b89828701611fd4565b82840152505080945050602085013591508082111561216957600080fd5b50611f3485828601611e1c565b60006020828403121561218857600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611def57600080fd5b6000806000606084860312156121c257600080fd5b6121cb8461218f565b92506121d96020850161218f565b9150604084015163ffffffff811681146121f257600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261226157600080fd5b83018035915067ffffffffffffffff82111561227c57600080fd5b60200191503681900382131561229157600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156115935761159361235a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b818103818111156115935761159361235a565b61ffff8281168282160390808211156123f9576123f961235a565b5092915050565b80820281158282048414176115935761159361235a565b60008261244d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561246457600080fd5b8151801515811461247457600080fd5b9392505050565b60005b8381101561249657818101518382015260200161247e565b50506000910152565b600082516124b181846020870161247b565b9190910192915050565b60208152600082518060208401526124da81604085016020870161247b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220200d00eba2c244bcc4394586e11bed52f1bde27d737f84e6823312ec945bdf2064736f6c63430008130033", + "numDeployments": 10, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"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\":\"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\":\"uniswapV2LikeExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"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\":\"uniswapV2LikeExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\\n * NOTE: The tokens must already have been moved to the first pool\\n */\\n function uniswapV2LikeExactInputSingleInternal(\\n ExactInputSingleParams memory params\\n ) internal returns (uint256 amountOut) {\\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\\n } else {\\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\\n }\\n\\n return uniswapV2LikeExactInputSingleInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 the pool\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n params.pool,\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n\\n return uniswapV2LikeExactInputSingleInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputInternal(\\n ExactInputParams calldata params\\n ) internal returns (uint256 amountOut) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n address[] memory tokens = params.tokens;\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = tokens[0] == address(0);\\n bool isToEth = tokens[poolLength] == address(0);\\n\\n if (isFromEth) {\\n tokens[0] = address(s.weth);\\n }\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : tokens[0],\\n isToEth ? address(0) : tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokens[0] == address(0)) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\\n }\\n\\n return uniswapV2LikeExactInputInternal(params);\\n }\\n\\n function uniswapV2LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\n // Permit tokens / set allowance\\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n\\n return uniswapV2LikeExactInputInternal(params);\\n }\\n}\\n\",\"keccak256\":\"0x2264d60e017f7ec8aa13691a2cabd116d785824587c832a5cb8dbaa5336599c1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV2Like is ILibStarVault, ILibWarp {\\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 ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInputSinglePermit(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInputPermit(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x61257f389c4a69c463baafad1a008ed2e9d68936a7e4a2cbe5a0cdc60df61e40\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b5061299a806100206000396000f3fe60806040526004361061003f5760003560e01c806311f1fdef14610044578063baa8ed3514610076578063c83ee48414610089578063d1b72bc41461009c575b600080fd5b34801561005057600080fd5b5061006461005f366004612268565b6100bc565b60405190815260200160405180910390f35b6100646100843660046122b9565b610319565b6100646100973660046122e9565b61052d565b3480156100a857600080fd5b506100646100b736600461231e565b610766565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610126906101008c01908c016123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161015d6101608b016101408c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161018f61016089016101408a016123d2565b65ffffffffffff1690526101a660208701876123ed565b6040518563ffffffff1660e01b81526004016101c59493929190612459565b600060405180830381600087803b1580156101df57600080fd5b505af11580156101f3573d6000803e3d6000fd5b5050505061021e7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c785163361024e60808701606088016123a1565b8635610261610100890160e08a016123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102df57600080fd5b505af11580156102f3573d6000803e3d6000fd5b505050506103108380360381019061030b91906125ad565b610a0c565b90505b92915050565b600061032d610160830161014084016123d2565b65ffffffffffff1642111561036e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610381610100840160e085016123a1565b73ffffffffffffffffffffffffffffffffffffffff16036104d657348235146103d6576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561046257600080fd5b505af1158015610476573d6000803e3d6000fd5b50505050506104d182606001602081019061049191906123a1565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff169084356110ca565b61051b565b61051b336104ea60808501606086016123a1565b84356104fd610100870160e088016123a1565b73ffffffffffffffffffffffffffffffffffffffff169291906111a3565b61031361030b368490038401846125ad565b600061053f60e0830160c084016123d2565b65ffffffffffff16421115610580576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610590610100840184612679565b60008181106105a1576105a16126e1565b90506020020160208101906105b691906123a1565b73ffffffffffffffffffffffffffffffffffffffff16036106ef573482351461060b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561069757600080fd5b505af11580156106ab573d6000803e3d6000fd5b50505050506106ea828061012001906106c49190612679565b60008181106106d5576106d56126e1565b905060200201602081019061049191906123a1565b61075d565b61075d33610701610120850185612679565b6000818110610712576107126126e1565b905060200201602081019061072791906123a1565b8435610737610100870187612679565b6000818110610748576107486126e1565b90506020020160208101906104fd91906123a1565b61031382611207565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915260009173ffffffffffffffffffffffffffffffffffffffff1690632b67b5709033908060608101806107c96101008b018b612679565b60008181106107da576107da6126e1565b90506020020160208101906107ef91906123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161082460e08b0160c08c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161085460e0890160c08a016123d2565b65ffffffffffff16905261086b60208701876123ed565b6040518563ffffffff1660e01b815260040161088a9493929190612459565b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506108e37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633610911610120870187612679565b6000818110610922576109226126e1565b905060200201602081019061093791906123a1565b8635610947610100890189612679565b6000818110610958576109586126e1565b905060200201602081019061096d91906123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050505061031083611207565b60e08101516101008201516000917f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff918216159116158381610af8576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af39190612710565b610afa565b475b90508215610b2057835473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8115610b4557835473ffffffffffffffffffffffffffffffffffffffff166101008701525b600080876060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915087610100015173ffffffffffffffffffffffffffffffffffffffff168860e0015173ffffffffffffffffffffffffffffffffffffffff161115610c1f57905b610120880151885161ffff6127109283031691840290820290810190830281610c4a57610c4a612797565b04975050610c6088602001518960a00151611b42565b871015610c99576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1610610cde576000610ce1565b60015b9050886060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610d0e5789610d11565b60005b83610d1d576000610d1f565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015610d8957600080fd5b505af1158015610d9d573d6000803e3d6000fd5b505050506101008901516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190612710565b905084811080610e4f5750610e4c89866127f5565b81105b15610e86576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea88a60c001518b61010001518c6080015161ffff168d602001518d611b69565b98508515610fd75787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d8060008114610f91576040519150601f19603f3d011682016040523d82523d6000602084013e610f96565b606091505b5050905080610fd1576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061100b565b61100b8a604001518a8c610100015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b8561101b5789610100015161101e565b60005b73ffffffffffffffffffffffffffffffffffffffff1687611043578a60e00151611046565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518d6040516110b5929190918252602082015260400190565b60405180910390a45050505050505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261119e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c22565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161111c565b50505050565b60007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1081611239610100850185612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061127b92505050610120860186612679565b9050905060008073ffffffffffffffffffffffffffffffffffffffff16836000815181106112ab576112ab6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168484815181106112f7576112f76126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115611387578454845173ffffffffffffffffffffffffffffffffffffffff90911690859060009061134c5761134c6126e1565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008161143f578484815181106113a0576113a06126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143a9190612710565b611441565b475b905060006114d061145560408b018b612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508c3591508990506114996101208e018e612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d3192505050565b90506114ef60208a01356114ea60a08c0160808d01612808565b611b42565b81600183516114fe9190612823565b8151811061150e5761150e6126e1565b6020026020010151101561154e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8581101561176f5760006115668260016127f5565b9050600088828151811061157c5761157c6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168984815181106115ac576115ac6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106115d65760006115d9565b60015b9050600060028a516115eb9190612823565b84106115f7573061162a565b6116056101208e018e612679565b84818110611615576116156126e1565b905060200201602081019061162a91906123a1565b905061163a6101208e018e612679565b8581811061164a5761164a6126e1565b905060200201602081019061165f91906123a1565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361169e57868581518110611691576116916126e1565b60200260200101516116a1565b60005b846116ad5760006116c8565b8786815181106116bf576116bf6126e1565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561174857600080fd5b505af115801561175c573d6000803e3d6000fd5b5050600190950194506115519350505050565b506000868681518110611784576117846126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190612710565b905082811080611836575061183389846127f5565b81105b1561186d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d66118816101008c0160e08d016123a1565b888881518110611893576118936126e1565b60200260200101518c60a00160208101906118ae9190612808565b61ffff168d60200135868b815181106118c9576118c96126e1565b6020026020010151611b69565b98508315611a125787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561194957600080fd5b505af115801561195d573d6000803e3d6000fd5b506000925061197591505060808c0160608d016123a1565b73ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146119cc576040519150601f19603f3d011682016040523d82523d6000602084013e6119d1565b606091505b5050905080611a0c576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611a65565b611a65611a2560808c0160608d016123a1565b8a898981518110611a3857611a386126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b83611a8957868681518110611a7c57611a7c6126e1565b6020026020010151611a8c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685611ac75787600081518110611aba57611aba6126e1565b6020026020010151611aca565b60005b73ffffffffffffffffffffffffffffffffffffffff16611af16101008d0160e08e016123a1565b604080518e358152602081018e905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f391016110b5565b6000612710611b518382612836565b611b5f9061ffff1685612858565b610310919061286f565b60006107d0841115611bb0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611bc2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611bf85760646032840204611bfb565b60005b9050808303838214611c1357611c138a8a8484611f66565b50505090910395945050505050565b6000611c84826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661202e9092919063ffffffff16565b9050805160001480611ca5575080806020019051810190611ca591906128aa565b61119e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611ba7565b805182516060919067ffffffffffffffff811115611d5157611d5161251b565b604051908082528060200260200182016040528015611d7a578160200160208202803683370190505b5091508482600081518110611d9157611d916126e1565b60200260200101818152505060005b81811015611f5c576000858281518110611dbc57611dbc6126e1565b60200260200101519050600086836001611dd691906127f5565b81518110611de657611de66126e1565b602002602001015190506000898481518110611e0457611e046126e1565b6020026020010151612710611e199190612836565b61ffff169050600080888681518110611e3457611e346126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115611f0557905b828b0282612710020181848d020281611f2057611f20612797565b049a508a88611f308860016127f5565b81518110611f4057611f406126e1565b6020908102919091010152505060019093019250611da0915050565b5050949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061203d8484600085612045565b949350505050565b6060824710156120d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611ba7565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161210091906128f7565b60006040518083038185875af1925050503d806000811461213d576040519150601f19603f3d011682016040523d82523d6000602084013e612142565b606091505b50915091506121538783838761215e565b979650505050505050565b606083156121f45782516000036121ed5773ffffffffffffffffffffffffffffffffffffffff85163b6121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611ba7565b508161203d565b61203d83838151156122095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79190612913565b6000610160828403121561225057600080fd5b50919050565b60006040828403121561225057600080fd5b600080610180838503121561227c57600080fd5b612286848461223d565b915061016083013567ffffffffffffffff8111156122a357600080fd5b6122af85828601612256565b9150509250929050565b600061016082840312156122cc57600080fd5b610310838361223d565b6000610140828403121561225057600080fd5b6000602082840312156122fb57600080fd5b813567ffffffffffffffff81111561231257600080fd5b61203d848285016122d6565b6000806040838503121561233157600080fd5b823567ffffffffffffffff8082111561234957600080fd5b612355868387016122d6565b9350602085013591508082111561236b57600080fd5b506122af85828601612256565b803573ffffffffffffffffffffffffffffffffffffffff8116811461239c57600080fd5b919050565b6000602082840312156123b357600080fd5b61031082612378565b803565ffffffffffff8116811461239c57600080fd5b6000602082840312156123e457600080fd5b610310826123bc565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261242257600080fd5b83018035915067ffffffffffffffff82111561243d57600080fd5b60200191503681900382131561245257600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715612595577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803561ffff8116811461239c57600080fd5b600061016082840312156125c057600080fd5b6125c861254a565b82358152602083013560208201526125e260408401612378565b60408201526125f360608401612378565b60608201526126046080840161259b565b608082015261261560a0840161259b565b60a082015261262660c08401612378565b60c082015261263760e08401612378565b60e082015261010061264a818501612378565b9082015261012061265c84820161259b565b9082015261014061266e8482016123bc565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126ae57600080fd5b83018035915067ffffffffffffffff8211156126c957600080fd5b6020019150600581901b360382131561245257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561272257600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461239c57600080fd5b60008060006060848603121561275c57600080fd5b61276584612729565b925061277360208501612729565b9150604084015163ffffffff8116811461278c57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610313576103136127c6565b60006020828403121561281a57600080fd5b6103108261259b565b81810381811115610313576103136127c6565b61ffff828116828216039080821115612851576128516127c6565b5092915050565b8082028115828204841417610313576103136127c6565b6000826128a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156128bc57600080fd5b815180151581146128cc57600080fd5b9392505050565b60005b838110156128ee5781810151838201526020016128d6565b50506000910152565b600082516129098184602087016128d3565b9190910192915050565b60208152600082518060208401526129328160408501602087016128d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de44c59485b64a44309171bd5ec5a3aa82d4e9417058be7ee66435ce87ad82ed64736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003f5760003560e01c806311f1fdef14610044578063baa8ed3514610076578063c83ee48414610089578063d1b72bc41461009c575b600080fd5b34801561005057600080fd5b5061006461005f366004612268565b6100bc565b60405190815260200160405180910390f35b6100646100843660046122b9565b610319565b6100646100973660046122e9565b61052d565b3480156100a857600080fd5b506100646100b736600461231e565b610766565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610126906101008c01908c016123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161015d6101608b016101408c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161018f61016089016101408a016123d2565b65ffffffffffff1690526101a660208701876123ed565b6040518563ffffffff1660e01b81526004016101c59493929190612459565b600060405180830381600087803b1580156101df57600080fd5b505af11580156101f3573d6000803e3d6000fd5b5050505061021e7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c785163361024e60808701606088016123a1565b8635610261610100890160e08a016123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156102df57600080fd5b505af11580156102f3573d6000803e3d6000fd5b505050506103108380360381019061030b91906125ad565b610a0c565b90505b92915050565b600061032d610160830161014084016123d2565b65ffffffffffff1642111561036e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610381610100840160e085016123a1565b73ffffffffffffffffffffffffffffffffffffffff16036104d657348235146103d6576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561046257600080fd5b505af1158015610476573d6000803e3d6000fd5b50505050506104d182606001602081019061049191906123a1565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff169084356110ca565b61051b565b61051b336104ea60808501606086016123a1565b84356104fd610100870160e088016123a1565b73ffffffffffffffffffffffffffffffffffffffff169291906111a3565b61031361030b368490038401846125ad565b600061053f60e0830160c084016123d2565b65ffffffffffff16421115610580576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610590610100840184612679565b60008181106105a1576105a16126e1565b90506020020160208101906105b691906123a1565b73ffffffffffffffffffffffffffffffffffffffff16036106ef573482351461060b576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561069757600080fd5b505af11580156106ab573d6000803e3d6000fd5b50505050506106ea828061012001906106c49190612679565b60008181106106d5576106d56126e1565b905060200201602081019061049191906123a1565b61075d565b61075d33610701610120850185612679565b6000818110610712576107126126e1565b905060200201602081019061072791906123a1565b8435610737610100870187612679565b6000818110610748576107486126e1565b90506020020160208101906104fd91906123a1565b61031382611207565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0810190915260009173ffffffffffffffffffffffffffffffffffffffff1690632b67b5709033908060608101806107c96101008b018b612679565b60008181106107da576107da6126e1565b90506020020160208101906107ef91906123a1565b73ffffffffffffffffffffffffffffffffffffffff90811682528a3516602082015260400161082460e08b0160c08c016123d2565b65ffffffffffff9081168252893516602091820152908252309082015260400161085460e0890160c08a016123d2565b65ffffffffffff16905261086b60208701876123ed565b6040518563ffffffff1660e01b815260040161088a9493929190612459565b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506108e37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b6001015473ffffffffffffffffffffffffffffffffffffffff166336c7851633610911610120870187612679565b6000818110610922576109226126e1565b905060200201602081019061093791906123a1565b8635610947610100890189612679565b6000818110610958576109586126e1565b905060200201602081019061096d91906123a1565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff9485166004820152928416602484015290831660448301529091166064820152608401600060405180830381600087803b1580156109eb57600080fd5b505af11580156109ff573d6000803e3d6000fd5b5050505061031083611207565b60e08101516101008201516000917f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff918216159116158381610af8576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af39190612710565b610afa565b475b90508215610b2057835473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8115610b4557835473ffffffffffffffffffffffffffffffffffffffff166101008701525b600080876060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915087610100015173ffffffffffffffffffffffffffffffffffffffff168860e0015173ffffffffffffffffffffffffffffffffffffffff161115610c1f57905b610120880151885161ffff6127109283031691840290820290810190830281610c4a57610c4a612797565b04975050610c6088602001518960a00151611b42565b871015610c99576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1610610cde576000610ce1565b60015b9050886060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610d0e5789610d11565b60005b83610d1d576000610d1f565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015610d8957600080fd5b505af1158015610d9d573d6000803e3d6000fd5b505050506101008901516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190612710565b905084811080610e4f5750610e4c89866127f5565b81105b15610e86576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea88a60c001518b61010001518c6080015161ffff168d602001518d611b69565b98508515610fd75787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d8060008114610f91576040519150601f19603f3d011682016040523d82523d6000602084013e610f96565b606091505b5050905080610fd1576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061100b565b61100b8a604001518a8c610100015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b8561101b5789610100015161101e565b60005b73ffffffffffffffffffffffffffffffffffffffff1687611043578a60e00151611046565b60005b73ffffffffffffffffffffffffffffffffffffffff168b60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38d600001518d6040516110b5929190918252602082015260400190565b60405180910390a45050505050505050919050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261119e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c22565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161111c565b50505050565b60007f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1081611239610100850185612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061127b92505050610120860186612679565b9050905060008073ffffffffffffffffffffffffffffffffffffffff16836000815181106112ab576112ab6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168484815181106112f7576112f76126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115611387578454845173ffffffffffffffffffffffffffffffffffffffff90911690859060009061134c5761134c6126e1565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008161143f578484815181106113a0576113a06126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611416573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143a9190612710565b611441565b475b905060006114d061145560408b018b612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508c3591508990506114996101208e018e612679565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250611d3192505050565b90506114ef60208a01356114ea60a08c0160808d01612808565b611b42565b81600183516114fe9190612823565b8151811061150e5761150e6126e1565b6020026020010151101561154e576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8581101561176f5760006115668260016127f5565b9050600088828151811061157c5761157c6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168984815181106115ac576115ac6126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106115d65760006115d9565b60015b9050600060028a516115eb9190612823565b84106115f7573061162a565b6116056101208e018e612679565b84818110611615576116156126e1565b905060200201602081019061162a91906123a1565b905061163a6101208e018e612679565b8581811061164a5761164a6126e1565b905060200201602081019061165f91906123a1565b73ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361169e57868581518110611691576116916126e1565b60200260200101516116a1565b60005b846116ad5760006116c8565b8786815181106116bf576116bf6126e1565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561174857600080fd5b505af115801561175c573d6000803e3d6000fd5b5050600190950194506115519350505050565b506000868681518110611784576117846126e1565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190612710565b905082811080611836575061183389846127f5565b81105b1561186d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118d66118816101008c0160e08d016123a1565b888881518110611893576118936126e1565b60200260200101518c60a00160208101906118ae9190612808565b61ffff168d60200135868b815181106118c9576118c96126e1565b6020026020010151611b69565b98508315611a125787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561194957600080fd5b505af115801561195d573d6000803e3d6000fd5b506000925061197591505060808c0160608d016123a1565b73ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146119cc576040519150601f19603f3d011682016040523d82523d6000602084013e6119d1565b606091505b5050905080611a0c576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611a65565b611a65611a2560808c0160608d016123a1565b8a898981518110611a3857611a386126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166110ca9092919063ffffffff16565b83611a8957868681518110611a7c57611a7c6126e1565b6020026020010151611a8c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685611ac75787600081518110611aba57611aba6126e1565b6020026020010151611aca565b60005b73ffffffffffffffffffffffffffffffffffffffff16611af16101008d0160e08e016123a1565b604080518e358152602081018e905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f391016110b5565b6000612710611b518382612836565b611b5f9061ffff1685612858565b610310919061286f565b60006107d0841115611bb0576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611bc2575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611bf85760646032840204611bfb565b60005b9050808303838214611c1357611c138a8a8484611f66565b50505090910395945050505050565b6000611c84826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661202e9092919063ffffffff16565b9050805160001480611ca5575080806020019051810190611ca591906128aa565b61119e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611ba7565b805182516060919067ffffffffffffffff811115611d5157611d5161251b565b604051908082528060200260200182016040528015611d7a578160200160208202803683370190505b5091508482600081518110611d9157611d916126e1565b60200260200101818152505060005b81811015611f5c576000858281518110611dbc57611dbc6126e1565b60200260200101519050600086836001611dd691906127f5565b81518110611de657611de66126e1565b602002602001015190506000898481518110611e0457611e046126e1565b6020026020010151612710611e199190612836565b61ffff169050600080888681518110611e3457611e346126e1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eaa9190612747565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115611f0557905b828b0282612710020181848d020281611f2057611f20612797565b049a508a88611f308860016127f5565b81518110611f4057611f406126e1565b6020908102919091010152505060019093019250611da0915050565b5050949350505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b606061203d8484600085612045565b949350505050565b6060824710156120d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611ba7565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161210091906128f7565b60006040518083038185875af1925050503d806000811461213d576040519150601f19603f3d011682016040523d82523d6000602084013e612142565b606091505b50915091506121538783838761215e565b979650505050505050565b606083156121f45782516000036121ed5773ffffffffffffffffffffffffffffffffffffffff85163b6121ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611ba7565b508161203d565b61203d83838151156122095781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba79190612913565b6000610160828403121561225057600080fd5b50919050565b60006040828403121561225057600080fd5b600080610180838503121561227c57600080fd5b612286848461223d565b915061016083013567ffffffffffffffff8111156122a357600080fd5b6122af85828601612256565b9150509250929050565b600061016082840312156122cc57600080fd5b610310838361223d565b6000610140828403121561225057600080fd5b6000602082840312156122fb57600080fd5b813567ffffffffffffffff81111561231257600080fd5b61203d848285016122d6565b6000806040838503121561233157600080fd5b823567ffffffffffffffff8082111561234957600080fd5b612355868387016122d6565b9350602085013591508082111561236b57600080fd5b506122af85828601612256565b803573ffffffffffffffffffffffffffffffffffffffff8116811461239c57600080fd5b919050565b6000602082840312156123b357600080fd5b61031082612378565b803565ffffffffffff8116811461239c57600080fd5b6000602082840312156123e457600080fd5b610310826123bc565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261242257600080fd5b83018035915067ffffffffffffffff82111561243d57600080fd5b60200191503681900382131561245257600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715612595577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803561ffff8116811461239c57600080fd5b600061016082840312156125c057600080fd5b6125c861254a565b82358152602083013560208201526125e260408401612378565b60408201526125f360608401612378565b60608201526126046080840161259b565b608082015261261560a0840161259b565b60a082015261262660c08401612378565b60c082015261263760e08401612378565b60e082015261010061264a818501612378565b9082015261012061265c84820161259b565b9082015261014061266e8482016123bc565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126ae57600080fd5b83018035915067ffffffffffffffff8211156126c957600080fd5b6020019150600581901b360382131561245257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561272257600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461239c57600080fd5b60008060006060848603121561275c57600080fd5b61276584612729565b925061277360208501612729565b9150604084015163ffffffff8116811461278c57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610313576103136127c6565b60006020828403121561281a57600080fd5b6103108261259b565b81810381811115610313576103136127c6565b61ffff828116828216039080821115612851576128516127c6565b5092915050565b8082028115828204841417610313576103136127c6565b6000826128a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156128bc57600080fd5b815180151581146128cc57600080fd5b9392505050565b60005b838110156128ee5781810151838201526020016128d6565b50506000910152565b600082516129098184602087016128d3565b9190910192915050565b60208152600082518060208401526129328160408501602087016128d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de44c59485b64a44309171bd5ec5a3aa82d4e9417058be7ee66435ce87ad82ed64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/UniV3Callback.json b/packages/hardhat/deployments/optimism/UniV3Callback.json index 63fe506b..92ad3b2c 100644 --- a/packages/hardhat/deployments/optimism/UniV3Callback.json +++ b/packages/hardhat/deployments/optimism/UniV3Callback.json @@ -1,5 +1,5 @@ { - "address": "0x195c3182320D98bA0F8443220FEB771a69438251", + "address": "0xb052C31125bd11a66431E1c4A735A1d965652C77", "abi": [ { "inputs": [], @@ -122,28 +122,28 @@ "type": "function" } ], - "transactionHash": "0x9404b1d8868e3204366f187e674600f64e12fbb939251cda4c2887731f1c2e5b", + "transactionHash": "0x4d1b060c9053b1117547fbd929c261178ae78eb64e6cf230a683446d7e165965", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x195c3182320D98bA0F8443220FEB771a69438251", - "transactionIndex": 3, - "gasUsed": "490767", + "contractAddress": "0xb052C31125bd11a66431E1c4A735A1d965652C77", + "transactionIndex": 2, + "gasUsed": "548027", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x13d3bc3af6c9373b69fa2c6273a01edce6be00a1b55a3b14ef384e6fbc1782c3", - "transactionHash": "0x9404b1d8868e3204366f187e674600f64e12fbb939251cda4c2887731f1c2e5b", + "blockHash": "0x3a758186956f2fc40f792e250367d2a766dcd3b40e134360b174a658cc742073", + "transactionHash": "0x4d1b060c9053b1117547fbd929c261178ae78eb64e6cf230a683446d7e165965", "logs": [], - "blockNumber": 111006671, - "cumulativeGasUsed": "827002", + "blockNumber": 111825951, + "cumulativeGasUsed": "624572", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 7, - "solcInputHash": "4a9aead708515414ed961374f1d066ed", - "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\":\"pancakeV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"ramsesV2SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swapCallback\",\"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\"},\"pancakeV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"ramsesV2SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"swapCallback(int256,int256,bytes)\":{\"notice\":\"KyperSwap V2 callback 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 /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * KyperSwap V2 callback\\n * NOTE: None of these arguments can be trusted\\n */\\n function swapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x85ecd0df604a102bbc22cbcfd07afec90fd4abb25b8fac2ce0bda48ba5663f82\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107f7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610687565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d5490911692820192909252903090036101c057805160408201516101bb9173ffffffffffffffffffffffffffffffffffffffff9091169033906102d2565b610288565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561026f57600080fd5b505af1158015610283573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261035f908490610364565b505050565b60006103c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104789092919063ffffffff16565b90508051600014806103e75750808060200190518101906103e79190610707565b61035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610487848460008561048f565b949350505050565b606082471015610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046f565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161054a9190610754565b60006040518083038185875af1925050503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d878383876105a8565b979650505050505050565b6060831561063e5782516000036106375773ffffffffffffffffffffffffffffffffffffffff85163b610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046f565b5081610487565b61048783838151156106535781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046f9190610770565b6000806000806060858703121561069d57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156106c357600080fd5b818701915087601f8301126106d757600080fd5b8135818111156106e657600080fd5b8860208285010111156106f857600080fd5b95989497505060200194505050565b60006020828403121561071957600080fd5b8151801515811461072957600080fd5b9392505050565b60005b8381101561074b578181015183820152602001610733565b50506000910152565b60008251610766818460208701610730565b9190910192915050565b602081526000825180602084015261078f816040850160208701610730565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e0c3a5ea77a59d4a136519a3fb790277ee65b84323dca008c9268c0208c1cb4364736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610687565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d5490911692820192909252903090036101c057805160408201516101bb9173ffffffffffffffffffffffffffffffffffffffff9091169033906102d2565b610288565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561026f57600080fd5b505af1158015610283573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261035f908490610364565b505050565b60006103c6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104789092919063ffffffff16565b90508051600014806103e75750808060200190518101906103e79190610707565b61035f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610487848460008561048f565b949350505050565b606082471015610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046f565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161054a9190610754565b60006040518083038185875af1925050503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d878383876105a8565b979650505050505050565b6060831561063e5782516000036106375773ffffffffffffffffffffffffffffffffffffffff85163b610637576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046f565b5081610487565b61048783838151156106535781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046f9190610770565b6000806000806060858703121561069d57600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156106c357600080fd5b818701915087601f8301126106d757600080fd5b8135818111156106e657600080fd5b8860208285010111156106f857600080fd5b95989497505060200194505050565b60006020828403121561071957600080fd5b8151801515811461072957600080fd5b9392505050565b60005b8381101561074b578181015183820152602001610733565b50506000910152565b60008251610766818460208701610730565b9190910192915050565b602081526000825180602084015261078f816040850160208701610730565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e0c3a5ea77a59d4a136519a3fb790277ee65b84323dca008c9268c0208c1cb4364736f6c63430008130033", + "numDeployments": 8, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "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\":\"pancakeV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"ramsesV2SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"swapCallback\",\"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\"},\"pancakeV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"ramsesV2SwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"swapCallback(int256,int256,bytes)\":{\"notice\":\"KyperSwap V2 callback 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 if (callback.usePermit == 1) {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n } else {\\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\\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 /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * KyperSwap V2 callback\\n * NOTE: None of these arguments can be trusted\\n */\\n function swapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xe3eb6dae32a233cc02e3aa833b2a7bac774a3c9c2c11f6d8feae8745d976f4b6\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610903806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610793565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e546060820152903090036101e757805160408201516101e29173ffffffffffffffffffffffffffffffffffffffff909116903390610339565b6102ef565b80606001516001036102bf577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156102a257600080fd5b505af11580156102b6573d6000803e3d6000fd5b505050506102ef565b6020810151815160408301516102ef9273ffffffffffffffffffffffffffffffffffffffff909116913390610412565b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261040d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610470565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526100899085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161038b565b60006104d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166105849092919063ffffffff16565b90508051600014806104f35750808060200190518101906104f39190610813565b61040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610593848460008561059b565b949350505050565b60608247101561062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161057b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106569190610860565b60006040518083038185875af1925050503d8060008114610693576040519150601f19603f3d011682016040523d82523d6000602084013e610698565b606091505b50915091506106a9878383876106b4565b979650505050505050565b6060831561074a5782516000036107435773ffffffffffffffffffffffffffffffffffffffff85163b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057b565b5081610593565b610593838381511561075f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b919061087c565b600080600080606085870312156107a957600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156107cf57600080fd5b818701915087601f8301126107e357600080fd5b8135818111156107f257600080fd5b88602082850101111561080457600080fd5b95989497505060200194505050565b60006020828403121561082557600080fd5b8151801515811461083557600080fd5b9392505050565b60005b8381101561085757818101518382015260200161083f565b50506000910152565b6000825161087281846020870161083c565b9190910192915050565b602081526000825180602084015261089b81604085016020870161083c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bd61054b7d7be6361f4cde7d339ff2b4e90fc18022d2e43caaa86ef48c70f7df64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063654b648711610050578063654b64871461006c578063fa461e331461006c578063fa483e721461006c57600080fd5b806323a69e751461006c5780632c8958f61461006c575b600080fd5b61007f61007a366004610793565b610081565b005b61008961008f565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100ed576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e546060820152903090036101e757805160408201516101e29173ffffffffffffffffffffffffffffffffffffffff909116903390610339565b6102ef565b80606001516001036102bf577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156102a257600080fd5b505af11580156102b6573d6000803e3d6000fd5b505050506102ef565b6020810151815160408301516102ef9273ffffffffffffffffffffffffffffffffffffffff909116913390610412565b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261040d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610470565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526100899085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161038b565b60006104d2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166105849092919063ffffffff16565b90508051600014806104f35750808060200190518101906104f39190610813565b61040d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610593848460008561059b565b949350505050565b60608247101561062d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161057b565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106569190610860565b60006040518083038185875af1925050503d8060008114610693576040519150601f19603f3d011682016040523d82523d6000602084013e610698565b606091505b50915091506106a9878383876106b4565b979650505050505050565b6060831561074a5782516000036107435773ffffffffffffffffffffffffffffffffffffffff85163b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057b565b5081610593565b610593838381511561075f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057b919061087c565b600080600080606085870312156107a957600080fd5b8435935060208501359250604085013567ffffffffffffffff808211156107cf57600080fd5b818701915087601f8301126107e357600080fd5b8135818111156107f257600080fd5b88602082850101111561080457600080fd5b95989497505060200194505050565b60006020828403121561082557600080fd5b8151801515811461083557600080fd5b9392505050565b60005b8381101561085757818101518382015260200161083f565b50506000910152565b6000825161087281846020870161083c565b9190910192915050565b602081526000825180602084015261089b81604085016020870161083c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220bd61054b7d7be6361f4cde7d339ff2b4e90fc18022d2e43caaa86ef48c70f7df64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/UniV3Like.json b/packages/hardhat/deployments/optimism/UniV3Like.json index f4a05689..8962315f 100644 --- a/packages/hardhat/deployments/optimism/UniV3Like.json +++ b/packages/hardhat/deployments/optimism/UniV3Like.json @@ -1,5 +1,5 @@ { - "address": "0x7B02C974D975ca1fcA6a48435cBafB13ADd5895a", + "address": "0xD9fd8268771eBF3701fBB28Ca7Cb8AEAbE0BAb4F", "abi": [ { "inputs": [], @@ -136,6 +136,72 @@ "name": "Warp", "type": "event" }, + { + "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" + } + ], + "name": "uniswapV3LikeExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -208,7 +274,78 @@ "type": "tuple" } ], - "name": "uniswapV3LikeExactInput", + "name": "uniswapV3LikeExactInputPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "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" + } + ], + "name": "uniswapV3LikeExactInputSingle", "outputs": [ { "internalType": "uint256", @@ -296,7 +433,7 @@ "type": "tuple" } ], - "name": "uniswapV3LikeExactInputSingle", + "name": "uniswapV3LikeExactInputSinglePermit", "outputs": [ { "internalType": "uint256", @@ -304,32 +441,32 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "nonpayable", "type": "function" } ], - "transactionHash": "0xbcf9b6ce5a2888040ec87e2759e80356bbf679e46e1d4a13a12eee11916e30f8", + "transactionHash": "0x96a0103b5592163da42a5aaf1b127e2a492a1e6c1133fb1c62a4c01af080919b", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x7B02C974D975ca1fcA6a48435cBafB13ADd5895a", - "transactionIndex": 4, - "gasUsed": "2039103", + "contractAddress": "0xD9fd8268771eBF3701fBB28Ca7Cb8AEAbE0BAb4F", + "transactionIndex": 7, + "gasUsed": "2135647", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x8b5ca389c9d8133e88fbb6a60165901aeff803524017274c51c2aafc7e7c2ff8", - "transactionHash": "0xbcf9b6ce5a2888040ec87e2759e80356bbf679e46e1d4a13a12eee11916e30f8", + "blockHash": "0x23af72653bf05b54bb8d4b52162817935c06ea9749927414b2d4b64fab176fc7", + "transactionHash": "0x96a0103b5592163da42a5aaf1b127e2a492a1e6c1133fb1c62a4c01af080919b", "logs": [], - "blockNumber": 111055250, - "cumulativeGasUsed": "2487915", + "blockNumber": 111825961, + "cumulativeGasUsed": "3310942", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 10, - "solcInputHash": "ff01f08786a3c11b5ff43becb123a9a3", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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/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 {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokenIn,\\n isToEth ? address(0) : params.tokenOut,\\n params.amountIn,\\n 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 = LibStarVault.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 emit LibWarp.Warp(\\n params.partner,\\n // NOTE: The tokens may have been rewritten to WETH\\n isFromEth ? address(0) : params.tokens[0],\\n isToEth ? address(0) : params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0778264b402de681401a9d1ca9ee9e1d313e2075b7d853b1504704a605ba6c23\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\\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\":\"0x61677478daa5f86ad18959bbe4a13b95a997853f844642be3f6eb54d6ab9a772\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50612421806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611de2565b610066565b60405190815260200160405180910390f35b610041610061366004611f8f565b6109f6565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029291906120a9565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff1681525089806020019061045191906120c2565b6040518563ffffffff1660e01b8152600401610470949392919061212e565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e91906121f0565b9150508061057b90612243565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906121f0565b50905061066381612243565b9550505b61066f61173b565b610682876101000151886060015161179b565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906120a9565b9050828110806107685750610765868461227b565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c188602001518960e001518a6040015161ffff168b61010001518a6117cb565b95508315610910577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108ca576040519150601f19603f3d011682016040523d82523d6000602084013e6108cf565b606091505b505090508061090a576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061093a565b875160e089015161093a9173ffffffffffffffffffffffffffffffffffffffff9091169088611884565b83610949578760e0015161094c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685610971578860c00151610974565b60005b73ffffffffffffffffffffffffffffffffffffffff16896020015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38b608001518a6040516109e3929190918252602082015260400190565b60405180910390a4505050505092915050565b60008260a0015165ffffffffffff16421115610a3e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e0840151805160009182918290610a5f57610a5f61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e001518481518110610aaf57610aaf61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610add5733610adf565b305b90508215610bfd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610b3b57610b3b61228e565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610b9a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b5050505050505b8115610c90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610c5557610c5561228e565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610ca857610ca861228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906120a9565b88519650905083610ed3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610ddb57610ddb61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610e8191906120c2565b6040518563ffffffff1660e01b8152600401610ea0949392919061212e565b600060405180830381600087803b158015610eba57600080fd5b505af1158015610ece573d6000803e3d6000fd5b505050505b60005b858110156111c457600081600101905060008a60e001518281518110610efe57610efe61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610f3257610f3261228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610fbf60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610f9957610f9961228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b80156110b65760008b61010001518481518110610fde57610fde61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a191906121f0565b915050806110ae90612243565b9950506111b1565b60008b610100015184815181106110cf576110cf61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906121f0565b5090506111ad81612243565b9950505b6111b961173b565b503093509050610ed6565b506111d386896060015161179b565b86101561120c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e0015186815181106112245761122461228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561129a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112be91906120a9565b9050818110806112d657506112d3878361227b565b81105b1561130d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113478960c001518a60e00151888151811061132b5761132b61228e565b60200260200101518b6080015161ffff168c602001518b6117cb565b96508315611496577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156113da57600080fd5b505af11580156113ee573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611450576040519150601f19603f3d011682016040523d82523d6000602084013e611455565b606091505b5050905080611490576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506114e2565b6114e28960400151888b60e0015189815181106114b5576114b561228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166118849092919063ffffffff16565b8361150a578860e0015186815181106114fd576114fd61228e565b602002602001015161150d565b60005b73ffffffffffffffffffffffffffffffffffffffff168561154c578960e0015160008151811061153f5761153f61228e565b602002602001015161154f565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b6040516115be929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611630576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611799576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60006127106117aa83826122bd565b6117b89061ffff16856122df565b6117c291906122f6565b90505b92915050565b60006107d0841115611812576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611824575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561185a576064603284020461185d565b60005b9050808303838214611875576118758a8a8484611916565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526119119084906119de565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611a40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611aed9092919063ffffffff16565b9050805160001480611a61575080806020019051810190611a619190612331565b611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611809565b6060611afc8484600085611b04565b949350505050565b606082471015611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611809565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbf919061237e565b60006040518083038185875af1925050503d8060008114611bfc576040519150601f19603f3d011682016040523d82523d6000602084013e611c01565b606091505b5091509150611c1287838387611c1d565b979650505050505050565b60608315611cb3578251600003611cac5773ffffffffffffffffffffffffffffffffffffffff85163b611cac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611809565b5081611afc565b611afc8383815115611cc85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611809919061239a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b60405290565b604051610120810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d9d57600080fd5b919050565b803561ffff81168114611d9d57600080fd5b803565ffffffffffff81168114611d9d57600080fd5b600060408284031215611ddc57600080fd5b50919050565b600080828403610160811215611df757600080fd5b61014080821215611e0757600080fd5b611e0f611d2b565b9150611e1a85611d79565b8252611e2860208601611d79565b6020830152611e3960408601611da2565b6040830152611e4a60608601611da2565b606083015260808501356080830152611e6560a08601611db4565b60a0830152611e7660c08601611d79565b60c0830152611e8760e08601611d79565b60e08301526101008581013590830152610120611ea5818701611d79565b9083015290925083013567ffffffffffffffff811115611ec457600080fd5b611ed085828601611dca565b9150509250929050565b600082601f830112611eeb57600080fd5b8135602067ffffffffffffffff80831115611f0857611f08611cfc565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611f4b57611f4b611cfc565b604052938452858101830193838101925087851115611f6957600080fd5b83870191505b84821015611c1257611f8082611d79565b83529183019190830190611f6f565b60008060408385031215611fa257600080fd5b823567ffffffffffffffff80821115611fba57600080fd5b908401906101208287031215611fcf57600080fd5b611fd7611d55565b8235815260208301356020820152611ff160408401611d79565b604082015261200260608401611da2565b606082015261201360808401611da2565b608082015261202460a08401611db4565b60a082015261203560c08401611d79565b60c082015260e08301358281111561204c57600080fd5b61205888828601611eda565b60e083015250610100808401358381111561207257600080fd5b61207e89828701611eda565b82840152505080945050602085013591508082111561209c57600080fd5b50611ed085828601611dca565b6000602082840312156120bb57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120f757600080fd5b83018035915067ffffffffffffffff82111561211257600080fd5b60200191503681900382131561212757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561220357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361227457612274612214565b5060000390565b808201808211156117c5576117c5612214565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156122d8576122d8612214565b5092915050565b80820281158282048414176117c5576117c5612214565b60008261232c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561234357600080fd5b8151801515811461235357600080fd5b9392505050565b60005b8381101561237557818101518382015260200161235d565b50506000910152565b6000825161239081846020870161235a565b9190910192915050565b60208152600082518060208401526123b981604085016020870161235a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220576050a04e57b56eff16cf6c316bc8966ab4a176dcea2edf74c13dd26adc111164736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611de2565b610066565b60405190815260200160405180910390f35b610041610061366004611f8f565b6109f6565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029291906120a9565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff1681525089806020019061045191906120c2565b6040518563ffffffff1660e01b8152600401610470949392919061212e565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e91906121f0565b9150508061057b90612243565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906121f0565b50905061066381612243565b9550505b61066f61173b565b610682876101000151886060015161179b565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075091906120a9565b9050828110806107685750610765868461227b565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c188602001518960e001518a6040015161ffff168b61010001518a6117cb565b95508315610910577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085457600080fd5b505af1158015610868573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108ca576040519150601f19603f3d011682016040523d82523d6000602084013e6108cf565b606091505b505090508061090a576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061093a565b875160e089015161093a9173ffffffffffffffffffffffffffffffffffffffff9091169088611884565b83610949578760e0015161094c565b60005b73ffffffffffffffffffffffffffffffffffffffff1685610971578860c00151610974565b60005b73ffffffffffffffffffffffffffffffffffffffff16896020015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38b608001518a6040516109e3929190918252602082015260400190565b60405180910390a4505050505092915050565b60008260a0015165ffffffffffff16421115610a3e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e0840151805160009182918290610a5f57610a5f61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e001518481518110610aaf57610aaf61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610add5733610adf565b305b90508215610bfd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610b3b57610b3b61228e565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610b9a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610be257600080fd5b505af1158015610bf6573d6000803e3d6000fd5b5050505050505b8115610c90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610c5557610c5561228e565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610ca857610ca861228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4291906120a9565b88519650905083610ed3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610ddb57610ddb61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610e8191906120c2565b6040518563ffffffff1660e01b8152600401610ea0949392919061212e565b600060405180830381600087803b158015610eba57600080fd5b505af1158015610ece573d6000803e3d6000fd5b505050505b60005b858110156111c457600081600101905060008a60e001518281518110610efe57610efe61228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610f3257610f3261228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610fbf60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610f9957610f9961228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506115d2565b80156110b65760008b61010001518481518110610fde57610fde61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a191906121f0565b915050806110ae90612243565b9950506111b1565b60008b610100015184815181106110cf576110cf61228e565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906121f0565b5090506111ad81612243565b9950505b6111b961173b565b503093509050610ed6565b506111d386896060015161179b565b86101561120c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e0015186815181106112245761122461228e565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561129a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112be91906120a9565b9050818110806112d657506112d3878361227b565b81105b1561130d576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113478960c001518a60e00151888151811061132b5761132b61228e565b60200260200101518b6080015161ffff168c602001518b6117cb565b96508315611496577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156113da57600080fd5b505af11580156113ee573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611450576040519150601f19603f3d011682016040523d82523d6000602084013e611455565b606091505b5050905080611490576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506114e2565b6114e28960400151888b60e0015189815181106114b5576114b561228e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166118849092919063ffffffff16565b8361150a578860e0015186815181106114fd576114fd61228e565b602002602001015161150d565b60005b73ffffffffffffffffffffffffffffffffffffffff168561154c578960e0015160008151811061153f5761153f61228e565b602002602001015161154f565b60005b73ffffffffffffffffffffffffffffffffffffffff168a60c0015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c600001518b6040516115be929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611630576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611799576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60006127106117aa83826122bd565b6117b89061ffff16856122df565b6117c291906122f6565b90505b92915050565b60006107d0841115611812576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611824575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561185a576064603284020461185d565b60005b9050808303838214611875576118758a8a8484611916565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526119119084906119de565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611a40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611aed9092919063ffffffff16565b9050805160001480611a61575080806020019051810190611a619190612331565b611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611809565b6060611afc8484600085611b04565b949350505050565b606082471015611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611809565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611bbf919061237e565b60006040518083038185875af1925050503d8060008114611bfc576040519150601f19603f3d011682016040523d82523d6000602084013e611c01565b606091505b5091509150611c1287838387611c1d565b979650505050505050565b60608315611cb3578251600003611cac5773ffffffffffffffffffffffffffffffffffffffff85163b611cac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611809565b5081611afc565b611afc8383815115611cc85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611809919061239a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b60405290565b604051610120810167ffffffffffffffff81118282101715611d4f57611d4f611cfc565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d9d57600080fd5b919050565b803561ffff81168114611d9d57600080fd5b803565ffffffffffff81168114611d9d57600080fd5b600060408284031215611ddc57600080fd5b50919050565b600080828403610160811215611df757600080fd5b61014080821215611e0757600080fd5b611e0f611d2b565b9150611e1a85611d79565b8252611e2860208601611d79565b6020830152611e3960408601611da2565b6040830152611e4a60608601611da2565b606083015260808501356080830152611e6560a08601611db4565b60a0830152611e7660c08601611d79565b60c0830152611e8760e08601611d79565b60e08301526101008581013590830152610120611ea5818701611d79565b9083015290925083013567ffffffffffffffff811115611ec457600080fd5b611ed085828601611dca565b9150509250929050565b600082601f830112611eeb57600080fd5b8135602067ffffffffffffffff80831115611f0857611f08611cfc565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611f4b57611f4b611cfc565b604052938452858101830193838101925087851115611f6957600080fd5b83870191505b84821015611c1257611f8082611d79565b83529183019190830190611f6f565b60008060408385031215611fa257600080fd5b823567ffffffffffffffff80821115611fba57600080fd5b908401906101208287031215611fcf57600080fd5b611fd7611d55565b8235815260208301356020820152611ff160408401611d79565b604082015261200260608401611da2565b606082015261201360808401611da2565b608082015261202460a08401611db4565b60a082015261203560c08401611d79565b60c082015260e08301358281111561204c57600080fd5b61205888828601611eda565b60e083015250610100808401358381111561207257600080fd5b61207e89828701611eda565b82840152505080945050602085013591508082111561209c57600080fd5b50611ed085828601611dca565b6000602082840312156120bb57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126120f757600080fd5b83018035915067ffffffffffffffff82111561211257600080fd5b60200191503681900382131561212757600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561220357600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361227457612274612214565b5060000390565b808201808211156117c5576117c5612214565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156122d8576122d8612214565b5092915050565b80820281158282048414176117c5576117c5612214565b60008261232c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561234357600080fd5b8151801515811461235357600080fd5b9392505050565b60005b8381101561237557818101518382015260200161235d565b50506000910152565b6000825161239081846020870161235a565b9190910192915050565b60208152600082518060208401526123b981604085016020870161235a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220576050a04e57b56eff16cf6c316bc8966ab4a176dcea2edf74c13dd26adc111164736f6c63430008130033", + "numDeployments": 11, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"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\"}],\"name\":\"uniswapV3LikeExactInput\",\"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\":\"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\":\"uniswapV3LikeExactInputPermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"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\":\"uniswapV3LikeExactInputSinglePermit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"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\"},\"@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/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 {LibStarVault} from '../libraries/LibStarVault.sol';\\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\\n ExactInputSingleParams calldata params,\\n uint256 usePermit\\n ) internal returns (uint256 amountOut) {\\n bool isFromEth = params.tokenIn == address(0);\\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\\n\\n address tokenOut = params.tokenOut == address(0)\\n ? address(LibWarp.state().weth)\\n : params.tokenOut;\\n\\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = tokenIn < tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: tokenIn,\\n amount: params.amountIn,\\n usePermit: usePermit\\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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (params.tokenOut == address(0)) {\\n // To ETH, unwrap WETH\\n // TODO: This is read twice. Compare gas usage\\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(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn == address(0)) {\\n // From ETH, wrap it\\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\\n }\\n\\n function uniswapV3LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\\n }\\n\\n function uniswapV3LikeExactInputInternal(\\n ExactInputParams calldata params,\\n uint256 usePermit\\n ) internal returns (uint256 amountOut) {\\n uint256 poolLength = params.pools.length;\\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\\n address[] memory tokens = params.tokens;\\n\\n if (params.tokens[0] == address(0)) {\\n tokens[0] = address(LibWarp.state().weth);\\n }\\n\\n if (params.tokens[poolLength] == address(0)) {\\n tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: payer,\\n token: tokens[index],\\n amount: amountOut,\\n usePermit: usePermit\\n })\\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(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 = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (params.tokens[poolLength] == address(0)) {\\n // To ETH, unwrap\\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n\\n emit LibWarp.Warp(\\n params.partner,\\n params.tokens[0],\\n params.tokens[poolLength],\\n params.amountIn,\\n amountOut\\n );\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokens[0] == address(0)) {\\n // From ETH, wrap it\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n LibWarp.state().weth.deposit{value: msg.value}();\\n }\\n\\n return uniswapV3LikeExactInputInternal(params, 0);\\n }\\n\\n function uniswapV3LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut) {\\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 return uniswapV3LikeExactInputInternal(params, 1);\\n }\\n}\\n\",\"keccak256\":\"0x9e23653ffdee1ddba14b812d0ed30da1b28d009e139fef4562407e722f5c541f\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\\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 calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInputSinglePermit(\\n ExactInputSingleParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams calldata params\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInputPermit(\\n ExactInputParams calldata params,\\n PermitParams calldata permit\\n ) external returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x1fbea0694f83750cccdc1e2e316bc7466e7d04e7342fd7d4359459f056d30a71\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"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/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b506125e1806100206000396000f3fe60806040526004361061003e5760003560e01c80626ee8b6146100435780635576abd114610068578063a33aea141461007b578063cda932d11461009b575b600080fd5b610056610051366004612064565b6100bb565b60405190815260200160405180910390f35b6100566100763660046120ac565b61024f565b34801561008757600080fd5b506100566100963660046120db565b6103b2565b3480156100a757600080fd5b506100566100b636600461212c565b6104fc565b60006100cd60c0830160a08401612186565b65ffffffffffff1642111561010e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061011d60e08401846121ae565b600081811061012e5761012e61221d565b9050602002016020810190610143919061224c565b73ffffffffffffffffffffffffffffffffffffffff160361023e5734823514610198576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b50505050505b61024982600061065b565b92915050565b600061026160c0830160a08401612186565b65ffffffffffff164211156102a2576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b460e0840160c0850161224c565b73ffffffffffffffffffffffffffffffffffffffff16036103a7577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660808301353414610344576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561038c57600080fd5b505af11580156103a0573d6000803e3d6000fd5b5050505050505b610249826000611118565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b57091339181906060820190819061041a908b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff908116825260808b013516602082015260400161045260c08b0160a08c01612186565b65ffffffffffff9081168252893516602091820152908252309082015260400161048260c0890160a08a01612186565b65ffffffffffff1690526104996020870187612282565b6040518563ffffffff1660e01b81526004016104b894939291906122e7565b600060405180830381600087803b1580156104d257600080fd5b505af11580156104e6573d6000803e3d6000fd5b505050506104f5836001611118565b9392505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610561908b018b6121ae565b60008181106105725761057261221d565b9050602002016020810190610587919061224c565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016105bc60c08b0160a08c01612186565b65ffffffffffff908116825289351660209182015290825230908201526040016105ec60c0890160a08a01612186565b65ffffffffffff1690526106036020870187612282565b6040518563ffffffff1660e01b815260040161062294939291906122e7565b600060405180830381600087803b15801561063c57600080fd5b505af1158015610650573d6000803e3d6000fd5b505050506104f58360015b60008061066c6101008501856121ae565b9150600090508061068060e08701876121ae565b60008181106106915761069161221d565b90506020020160208101906106a6919061224c565b73ffffffffffffffffffffffffffffffffffffffff16146106c757336106c9565b305b905060006106da60e08701876121ae565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061071b9250505060e08801886121ae565b600081811061072c5761072c61221d565b9050602002016020810190610741919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036107e5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff9091169082906000906107aa576107aa61221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f460e08801886121ae565b858181106108045761080461221d565b9050602002016020810190610819919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036108be577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff909116908290859081106108835761088361221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008184815181106108d2576108d261221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c91906123a9565b87359550905060005b84811015610c8157600081600101905060008482815181106109995761099961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168584815181106109c9576109c961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610a5860405180608001604052808a81526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878681518110610a2c57610a2c61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018b815250611904565b8015610b61576000610a6e6101008c018c6121ae565b85818110610a7e57610a7e61221d565b9050602002016020810190610a93919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c91906123c2565b91505080610b5990612415565b985050610c6e565b6000610b716101008c018c6121ae565b85818110610b8157610b8161221d565b9050602002016020810190610b96919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5e91906123c2565b509050610c6a81612415565b9850505b610c76611a93565b503094509050610975565b50610c9b85610c9660808a0160608b0161244d565b611af3565b851015610cd4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828581518110610ce857610ce861221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8291906123a9565b905081811080610d9a5750610d978683612471565b81105b15610dd1576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e20610de460e08a0160c08b0161224c565b848781518110610df657610df661221d565b60200260200101518a6080016020810190610e11919061244d565b61ffff168b602001358a611b1a565b95506000610e3160e08a018a6121ae565b87818110610e4157610e4161221d565b9050602002016020810190610e56919061224c565b73ffffffffffffffffffffffffffffffffffffffff1603610fc5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b5060009250610f2891505060608a0160408b0161224c565b73ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610f7f576040519150601f19603f3d011682016040523d82523d6000602084013e610f84565b606091505b5050905080610fbf576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611018565b611018610fd860608a0160408b0161224c565b87858881518110610feb57610feb61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611bd39092919063ffffffff16565b61102560e08901896121ae565b868181106110355761103561221d565b905060200201602081019061104a919061224c565b73ffffffffffffffffffffffffffffffffffffffff1661106d60e08a018a6121ae565b600081811061107e5761107e61221d565b9050602002016020810190611093919061224c565b73ffffffffffffffffffffffffffffffffffffffff166110b960e08b0160c08c0161224c565b604080518c358152602081018b905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050505092915050565b6000808061112c60e0860160c0870161224c565b73ffffffffffffffffffffffffffffffffffffffff161490506000816111615761115c60e0860160c0870161224c565b61119a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b90506000806111b0610100880160e0890161224c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576111dc610100870160e0880161224c565b61121a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae91906123a9565b905060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610905061134860405180608001604052808a608001358152602001876113065733611308565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200189815250611904565b80156114335760006113626101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b013560448201526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e91906123c2565b9150508061142b90612415565b965050611522565b60006114476101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b0135604482015273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151291906123c2565b50905061151e81612415565b9650505b61152a611a93565b611543610100890135610c9660808b0160608c0161244d565b86101561157c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d91906123a9565b90508281108061162557506116228784612471565b81105b1561165c576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61169061166f60408b0160208c0161224c565b8561168060608d0160408e0161244d565b61ffff168c61010001358b611b1a565b965060006116a56101008b0160e08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1603611811577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d80600081146117cb576040519150601f19603f3d011682016040523d82523d6000602084013e6117d0565b606091505b505090508061180b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061183f565b61183f61182160208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff86169089611bd3565b6118506101008a0160e08b0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661187660e08b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661189c60408c0160208d0161224c565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c608001358b6040516118f0929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611962576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611af1576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612710611b028382612484565b611b109061ffff16856124a6565b6104f591906124bd565b60006107d0841115611b61576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611b73575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611ba95760646032840204611bac565b60005b9050808303838214611bc457611bc48a8a8484611c65565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611c60908490611d2d565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611d8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e3c9092919063ffffffff16565b9050805160001480611db0575080806020019051810190611db091906124f8565b611c60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611b58565b6060611e4b8484600085611e53565b949350505050565b606082471015611ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611b58565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611f0e919061253e565b60006040518083038185875af1925050503d8060008114611f4b576040519150601f19603f3d011682016040523d82523d6000602084013e611f50565b606091505b5091509150611f6187838387611f6c565b979650505050505050565b60608315612002578251600003611ffb5773ffffffffffffffffffffffffffffffffffffffff85163b611ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611b58565b5081611e4b565b611e4b83838151156120175781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b58919061255a565b6000610120828403121561205e57600080fd5b50919050565b60006020828403121561207657600080fd5b813567ffffffffffffffff81111561208d57600080fd5b611e4b8482850161204b565b6000610140828403121561205e57600080fd5b600061014082840312156120bf57600080fd5b6104f58383612099565b60006040828403121561205e57600080fd5b60008061016083850312156120ef57600080fd5b6120f98484612099565b915061014083013567ffffffffffffffff81111561211657600080fd5b612122858286016120c9565b9150509250929050565b6000806040838503121561213f57600080fd5b823567ffffffffffffffff8082111561215757600080fd5b6121638683870161204b565b9350602085013591508082111561217957600080fd5b50612122858286016120c9565b60006020828403121561219857600080fd5b813565ffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126121e357600080fd5b83018035915067ffffffffffffffff8211156121fe57600080fd5b6020019150600581901b360382131561221657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561225e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122b757600080fd5b83018035915067ffffffffffffffff8211156122d257600080fd5b60200191503681900382131561221657600080fd5b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156123bb57600080fd5b5051919050565b600080604083850312156123d557600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203612446576124466123e6565b5060000390565b60006020828403121561245f57600080fd5b813561ffff811681146104f557600080fd5b80820180821115610249576102496123e6565b61ffff82811682821603908082111561249f5761249f6123e6565b5092915050565b8082028115828204841417610249576102496123e6565b6000826124f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561250a57600080fd5b815180151581146104f557600080fd5b60005b8381101561253557818101518382015260200161251d565b50506000910152565b6000825161255081846020870161251a565b9190910192915050565b602081526000825180602084015261257981604085016020870161251a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122020ef15a82dfe9e15884ad78a08e0e295c6c50a821511c6e99799a1a517eefc3564736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061003e5760003560e01c80626ee8b6146100435780635576abd114610068578063a33aea141461007b578063cda932d11461009b575b600080fd5b610056610051366004612064565b6100bb565b60405190815260200160405180910390f35b6100566100763660046120ac565b61024f565b34801561008757600080fd5b506100566100963660046120db565b6103b2565b3480156100a757600080fd5b506100566100b636600461212c565b6104fc565b60006100cd60c0830160a08401612186565b65ffffffffffff1642111561010e576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061011d60e08401846121ae565b600081811061012e5761012e61221d565b9050602002016020810190610143919061224c565b73ffffffffffffffffffffffffffffffffffffffff160361023e5734823514610198576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b50505050505b61024982600061065b565b92915050565b600061026160c0830160a08401612186565b65ffffffffffff164211156102a2576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102b460e0840160c0850161224c565b73ffffffffffffffffffffffffffffffffffffffff16036103a7577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660808301353414610344576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561038c57600080fd5b505af11580156103a0573d6000803e3d6000fd5b5050505050505b610249826000611118565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b57091339181906060820190819061041a908b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff908116825260808b013516602082015260400161045260c08b0160a08c01612186565b65ffffffffffff9081168252893516602091820152908252309082015260400161048260c0890160a08a01612186565b65ffffffffffff1690526104996020870187612282565b6040518563ffffffff1660e01b81526004016104b894939291906122e7565b600060405180830381600087803b1580156104d257600080fd5b505af11580156104e6573d6000803e3d6000fd5b505050506104f5836001611118565b9392505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e080820190925260009273ffffffffffffffffffffffffffffffffffffffff1691632b67b570913391819060608201908190610561908b018b6121ae565b60008181106105725761057261221d565b9050602002016020810190610587919061224c565b73ffffffffffffffffffffffffffffffffffffffff90811682528a351660208201526040016105bc60c08b0160a08c01612186565b65ffffffffffff908116825289351660209182015290825230908201526040016105ec60c0890160a08a01612186565b65ffffffffffff1690526106036020870187612282565b6040518563ffffffff1660e01b815260040161062294939291906122e7565b600060405180830381600087803b15801561063c57600080fd5b505af1158015610650573d6000803e3d6000fd5b505050506104f58360015b60008061066c6101008501856121ae565b9150600090508061068060e08701876121ae565b60008181106106915761069161221d565b90506020020160208101906106a6919061224c565b73ffffffffffffffffffffffffffffffffffffffff16146106c757336106c9565b305b905060006106da60e08701876121ae565b80806020026020016040519081016040528093929190818152602001838360200280828437600092018290525093945061071b9250505060e08801886121ae565b600081811061072c5761072c61221d565b9050602002016020810190610741919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036107e5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff9091169082906000906107aa576107aa61221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60006107f460e08801886121ae565b858181106108045761080461221d565b9050602002016020810190610819919061224c565b73ffffffffffffffffffffffffffffffffffffffff16036108be577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1054815173ffffffffffffffffffffffffffffffffffffffff909116908290859081106108835761088361221d565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008184815181106108d2576108d261221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c91906123a9565b87359550905060005b84811015610c8157600081600101905060008482815181106109995761099961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168584815181106109c9576109c961221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610a5860405180608001604052808a81526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878681518110610a2c57610a2c61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018b815250611904565b8015610b61576000610a6e6101008c018c6121ae565b85818110610a7e57610a7e61221d565b9050602002016020810190610a93919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c91906123c2565b91505080610b5990612415565b985050610c6e565b6000610b716101008c018c6121ae565b85818110610b8157610b8161221d565b9050602002016020810190610b96919061224c565b6040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018b905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af1158015610c3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5e91906123c2565b509050610c6a81612415565b9850505b610c76611a93565b503094509050610975565b50610c9b85610c9660808a0160608b0161244d565b611af3565b851015610cd4576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828581518110610ce857610ce861221d565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8291906123a9565b905081811080610d9a5750610d978683612471565b81105b15610dd1576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e20610de460e08a0160c08b0161224c565b848781518110610df657610df661221d565b60200260200101518a6080016020810190610e11919061244d565b61ffff168b602001358a611b1a565b95506000610e3160e08a018a6121ae565b87818110610e4157610e4161221d565b9050602002016020810190610e56919061224c565b73ffffffffffffffffffffffffffffffffffffffff1603610fc5577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b5060009250610f2891505060608a0160408b0161224c565b73ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610f7f576040519150601f19603f3d011682016040523d82523d6000602084013e610f84565b606091505b5050905080610fbf576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611018565b611018610fd860608a0160408b0161224c565b87858881518110610feb57610feb61221d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611bd39092919063ffffffff16565b61102560e08901896121ae565b868181106110355761103561221d565b905060200201602081019061104a919061224c565b73ffffffffffffffffffffffffffffffffffffffff1661106d60e08a018a6121ae565b600081811061107e5761107e61221d565b9050602002016020810190611093919061224c565b73ffffffffffffffffffffffffffffffffffffffff166110b960e08b0160c08c0161224c565b604080518c358152602081018b905273ffffffffffffffffffffffffffffffffffffffff92909216917f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3910160405180910390a4505050505092915050565b6000808061112c60e0860160c0870161224c565b73ffffffffffffffffffffffffffffffffffffffff161490506000816111615761115c60e0860160c0870161224c565b61119a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b90506000806111b0610100880160e0890161224c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576111dc610100870160e0880161224c565b61121a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff165b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae91906123a9565b905060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610905061134860405180608001604052808a608001358152602001876113065733611308565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200189815250611904565b80156114335760006113626101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b013560448201526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156113fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141e91906123c2565b9150508061142b90612415565b965050611522565b60006114476101408a016101208b0161224c565b6040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260808b0135604482015273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff919091169063128acb089060c40160408051808303816000875af11580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151291906123c2565b50905061151e81612415565b9650505b61152a611a93565b611543610100890135610c9660808b0160608c0161244d565b86101561157c576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d91906123a9565b90508281108061162557506116228784612471565b81105b1561165c576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61169061166f60408b0160208c0161224c565b8561168060608d0160408e0161244d565b61ffff168c61010001358b611b1a565b965060006116a56101008b0160e08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1603611811577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d80600081146117cb576040519150601f19603f3d011682016040523d82523d6000602084013e6117d0565b606091505b505090508061180b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061183f565b61183f61182160208b018b61224c565b73ffffffffffffffffffffffffffffffffffffffff86169089611bd3565b6118506101008a0160e08b0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661187660e08b0160c08c0161224c565b73ffffffffffffffffffffffffffffffffffffffff1661189c60408c0160208d0161224c565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38c608001358b6040516118f0929190918252602082015260400190565b60405180910390a450505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611962576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611af1576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612710611b028382612484565b611b109061ffff16856124a6565b6104f591906124bd565b60006107d0841115611b61576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611b73575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615611ba95760646032840204611bac565b60005b9050808303838214611bc457611bc48a8a8484611c65565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611c60908490611d2d565b505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6000611d8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e3c9092919063ffffffff16565b9050805160001480611db0575080806020019051810190611db091906124f8565b611c60576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611b58565b6060611e4b8484600085611e53565b949350505050565b606082471015611ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611b58565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611f0e919061253e565b60006040518083038185875af1925050503d8060008114611f4b576040519150601f19603f3d011682016040523d82523d6000602084013e611f50565b606091505b5091509150611f6187838387611f6c565b979650505050505050565b60608315612002578251600003611ffb5773ffffffffffffffffffffffffffffffffffffffff85163b611ffb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611b58565b5081611e4b565b611e4b83838151156120175781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b58919061255a565b6000610120828403121561205e57600080fd5b50919050565b60006020828403121561207657600080fd5b813567ffffffffffffffff81111561208d57600080fd5b611e4b8482850161204b565b6000610140828403121561205e57600080fd5b600061014082840312156120bf57600080fd5b6104f58383612099565b60006040828403121561205e57600080fd5b60008061016083850312156120ef57600080fd5b6120f98484612099565b915061014083013567ffffffffffffffff81111561211657600080fd5b612122858286016120c9565b9150509250929050565b6000806040838503121561213f57600080fd5b823567ffffffffffffffff8082111561215757600080fd5b6121638683870161204b565b9350602085013591508082111561217957600080fd5b50612122858286016120c9565b60006020828403121561219857600080fd5b813565ffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126121e357600080fd5b83018035915067ffffffffffffffff8211156121fe57600080fd5b6020019150600581901b360382131561221657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561225e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146104f557600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126122b757600080fd5b83018035915067ffffffffffffffff8211156122d257600080fd5b60200191503681900382131561221657600080fd5b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000602082840312156123bb57600080fd5b5051919050565b600080604083850312156123d557600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203612446576124466123e6565b5060000390565b60006020828403121561245f57600080fd5b813561ffff811681146104f557600080fd5b80820180821115610249576102496123e6565b61ffff82811682821603908082111561249f5761249f6123e6565b5092915050565b8082028115828204841417610249576102496123e6565b6000826124f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561250a57600080fd5b815180151581146104f557600080fd5b60005b8381101561253557818101518382015260200161251d565b50506000910152565b6000825161255081846020870161251a565b9190910192915050565b602081526000825180602084015261257981604085016020870161251a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122020ef15a82dfe9e15884ad78a08e0e295c6c50a821511c6e99799a1a517eefc3564736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/WarpLink.json b/packages/hardhat/deployments/optimism/WarpLink.json index 3358ad8d..82f4673b 100644 --- a/packages/hardhat/deployments/optimism/WarpLink.json +++ b/packages/hardhat/deployments/optimism/WarpLink.json @@ -1,5 +1,5 @@ { - "address": "0x5256c413F22Dafc7Db30531AD224Be948Ab12907", + "address": "0x9c115669E870Fe4B3B982D68932Fd083a520C10e", "abi": [ { "inputs": [], @@ -249,6 +249,71 @@ "stateMutability": "nonpayable", "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" + } + ], + "name": "warpLinkEngage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -326,34 +391,34 @@ "type": "tuple" } ], - "name": "warpLinkEngage", + "name": "warpLinkEngagePermit", "outputs": [], "stateMutability": "payable", "type": "function" } ], - "transactionHash": "0x1bd86afc8a0013cc7e740273789faf7f29d80ebeb7065819ce44863fecb96c00", + "transactionHash": "0x4e9e654c08b86d67ac059b113022687610bb6d595beb2926fa6e9144ecece2eb", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x5256c413F22Dafc7Db30531AD224Be948Ab12907", - "transactionIndex": 4, - "gasUsed": "4672465", + "contractAddress": "0x9c115669E870Fe4B3B982D68932Fd083a520C10e", + "transactionIndex": 11, + "gasUsed": "5125542", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xb9f6a596bb24886f04285ecea4c00976ba3667fd768bf3f6bab641990a4ef777", - "transactionHash": "0x1bd86afc8a0013cc7e740273789faf7f29d80ebeb7065819ce44863fecb96c00", + "blockHash": "0x0b6944e716303c26f33bf6fe246fae1479869418b70e6bdc641ef170a6efc2de", + "transactionHash": "0x4e9e654c08b86d67ac059b113022687610bb6d595beb2926fa6e9144ecece2eb", "logs": [], - "blockNumber": 111391115, - "cumulativeGasUsed": "5413020", + "blockNumber": 111825971, + "cumulativeGasUsed": "5828316", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 12, - "solcInputHash": "62b3897f582f2743ff2d0ddfebde07d0", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"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\":\"InvalidSgReceiveSrcAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSgReceiverSender\",\"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\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"bytes\",\"name\":\"_srcAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountLD\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sgReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{\"sgReceive(uint16,bytes,uint256,address,uint256,bytes)\":{\"notice\":\"Cross-chain callback from Stargate The tokens have already been received by this contract, `t.payer` is set to this contract before `sgReceive` is called by the router. The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the same message more than once. The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the Stargate composer be compromised, an attacker can drain this contract. If the payload can not be decoded, tokens are left in this contract. If execution runs out of gas, tokens are left in this contract. If an error occurs during engage, such as insufficient output amount, tokens are refunded to the recipient. See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\"}},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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';\\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\\n bytes payload;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n address paramTokenIn;\\n uint256 paramAmountIn;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint48 paramDeadline;\\n uint256 amount;\\n address payer;\\n address token;\\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 useEth: isFromEth || isToEth,\\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 * Cross-chain callback from Stargate\\n *\\n * The tokens have already been received by this contract, `t.payer` is set to this contract\\n * before `sgReceive` is called by the router.\\n *\\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\\n * same message more than once.\\n *\\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\\n * Stargate composer be compromised, an attacker can drain this contract.\\n *\\n * If the payload can not be decoded, tokens are left in this contract.\\n * If execution runs out of gas, tokens are left in this contract.\\n *\\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\\n * to the recipient.\\n *\\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\\n */\\n function sgReceive(\\n uint16, // _srcChainId\\n bytes memory _srcAddress,\\n uint256, // _nonce\\n address _token,\\n uint256 amountLD,\\n bytes memory payload\\n ) external {\\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\\n revert InvalidSgReceiverSender();\\n }\\n\\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\\n // From https://ethereum.stackexchange.com/a/50528\\n address srcAddress;\\n\\n assembly {\\n srcAddress := mload(add(_srcAddress, 20))\\n }\\n\\n if (srcAddress != address(this)) {\\n // NOTE: This assumes that this contract is deployed at the same address on every chain\\n revert InvalidSgReceiveSrcAddress();\\n }\\n\\n Params memory params = abi.decode(payload, (Params));\\n\\n if (params.tokenIn == address(0)) {\\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\\n // otherwise because `_token` may be different on this chain\\n _token = address(0);\\n }\\n\\n try\\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\\n Params({\\n partner: params.partner,\\n feeBps: params.feeBps,\\n slippageBps: params.slippageBps,\\n recipient: params.recipient,\\n tokenIn: _token,\\n tokenOut: params.tokenOut,\\n amountIn: amountLD,\\n amountOut: params.amountOut,\\n deadline: params.deadline,\\n commands: params.commands\\n }),\\n PermitParams({nonce: 0, signature: ''})\\n )\\n {} catch {\\n // Refund tokens to the recipient\\n if (_token == address(0)) {\\n payable(params.recipient).transfer(amountLD);\\n } else {\\n IERC20(_token).safeTransfer(params.recipient, amountLD);\\n }\\n }\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\\n * in this function.\\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 * - dstGasForCall (uint32)\\n * - tokenOut (address) when `dstGasForCall` > 0\\n * - amountOut (uint256) when `dstGasForCall` > 0\\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n params.dstGasForCall = stream.readUint32();\\n\\n if (params.dstGasForCall > 0) {\\n // NOTE: `amountIn` is left as zero\\n Params memory destParams;\\n destParams.partner = t.paramPartner;\\n destParams.feeBps = t.paramFeeBps;\\n destParams.slippageBps = t.paramSlippageBps;\\n destParams.recipient = t.paramRecipient;\\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\\n // the same address as on this chain\\n destParams.tokenIn = t.token;\\n destParams.tokenOut = stream.readAddress();\\n destParams.amountOut = stream.readUint256();\\n destParams.deadline = t.paramDeadline;\\n destParams.commands = stream.readBytes();\\n params.payload = abi.encode(destParams);\\n }\\n\\n if (t.token != t.paramTokenIn) {\\n if (params.payload.length == 0) {\\n // If the tokens are being delivered directly to the recipient without a second\\n // WarpLink engage, the fee is charged on this chain\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibStarVault.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n }\\n\\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\\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. When there is a payload, the composer is used, else the router\\n IERC20(t.token).forceApprove(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\\n t.amount\\n );\\n }\\n\\n t.jumped = 1;\\n\\n // Swap on the composer if there is a payload, else the router\\n IStargateRouter(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\\n ).swap{\\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\\n }({\\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\\n // more on the other chain. It also assumes the tokens are of nearly equal value\\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: params.dstGasForCall,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n // NOTE: This assumes the contract is deployed at the same address on every chain.\\n // If this is not the case, a new param needs to be added with the next WarpLink address\\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\\n _payload: params.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.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\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 // The signature is omitted when `warpLinkEngage` is called from `sgReceive`\\n if (permit.signature.length > 0) {\\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\\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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0x198e2bb767f975464f62ecb8578721d7516f8da1302b3acfd3c622258de1320e\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\\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 error InvalidSgReceiverSender();\\n error InvalidSgReceiveSrcAddress();\\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\":\"0xc1d8b9ba2a1f8300c00adc2c66fd51da23bb40db78ce5b7fe270bb7ee77e923e\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IStargateReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\n\\ninterface IStargateReceiver {\\n function sgReceive(\\n uint16 _srcChainId, // the remote chainId sending the tokens\\n bytes memory _srcAddress, // the remote Bridge address\\n uint256 _nonce,\\n address _token, // the token contract on the local chain\\n uint256 amountLD, // the qty of local _token contract tokens\\n bytes memory payload\\n ) external;\\n}\\n\",\"keccak256\":\"0x7fd06c09139156a4f09a77eac28e453a1d2041a8cf01a108fc875c65192cb637\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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\":\"0xce887d71117b221647d2230baed33ba3f3aa467b23a34262c8862cee234c584b\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50615400806100206000396000f3fe6080604052600436106100295760003560e01c8063ab8236f31461002e578063dc7b39db14610050575b600080fd5b34801561003a57600080fd5b5061004e610049366004614a1e565b610063565b005b61004e61005e366004614af2565b61036f565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff1633146100d6576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461012a576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906101409190614c9f565b608081015190915073ffffffffffffffffffffffffffffffffffffffff1661016757600094505b3063dc7b39db73ffffffffffffffffffffffffffffffffffffffff871615610190576000610192565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff168152602001856101200151815250604051806040016040528060008152602001604051806020016040528060008152508152506040518463ffffffff1660e01b81526004016102a4929190614efc565b6000604051808303818588803b1580156102bd57600080fd5b505af1935050505080156102cf575060015b6103655773ffffffffffffffffffffffffffffffffffffffff851661033e57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610338573d6000803e3d6000fd5b50610365565b60608101516103659073ffffffffffffffffffffffffffffffffffffffff87169086610981565b5050505050505050565b81610100015165ffffffffffff164211156103b6576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015161ffff9081169184019190915260408086018051831660c08087019182526060808a01518716948801949094526080808a01805188169589019590955290890180519188019190915260e0808a015160a0890152925190941690526101008088015165ffffffffffff169186019190915291519184019190915280518216610140840152511661052a578260c00151341015610509576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08301516105189034614f63565b610180820152306101208201526106bd565b336101208201523461018082015260006105476020840184614f76565b905011156106bd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff1681525085806020019061066b9190614f76565b6040518563ffffffff1660e01b815260040161068a9493929190614fe2565b600060405180830381600087803b1580156106a457600080fd5b505af11580156106b8573d6000803e3d6000fd5b505050505b60006106e2846101200151604080518082019091528181528151909101602082015290565b90506106ee8183610a5a565b61010081015161014082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610755576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107678660e001518760400151610c37565b8210156107a0576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361016001516001036107b557505050505050565b6107d686600001518760a00151886020015161ffff168960e0015186610c65565b915081600003610812576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661087d57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610877573d6000803e3d6000fd5b506108a4565b60608601516108a49073ffffffffffffffffffffffffffffffffffffffff83169084610981565b610180840151156108e257610180840151604051339180156108fc02916000818181858888f193505050501580156108e0573d6000803e3d6000fd5b505b8560a0015173ffffffffffffffffffffffffffffffffffffffff16866080015173ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c0015186604051610971929190918252602082015260400190565b60405180910390a4505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610d1e565b505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526000610ad58480516001018051915290565b60ff16905060005b81811015610c2b576000610af78680516001018051915290565b60ff16905060018103610b1457610b0d85610e2d565b9450610c18565b60028103610b2557610b0d85610ff5565b60038103610b3757610b0d8686611254565b60048103610b4957610b0d8686611832565b60058103610b5b57610b0d8686611bb9565b60068103610b6d57610b0d8686612367565b60078103610b7f57610b0d8686612891565b60088103610b9157610b0d8686612dcf565b60098103610be657610ba4600184614f63565b8214610bdc576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d8686613205565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5080610c23816150a4565b915050610add565b50829150505b92915050565b6000612710610c4683826150dc565b610c549061ffff16856150f7565b610c5e919061513d565b9392505050565b60006107d0841115610cac576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610cbe575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610cf45760646032840204610cf7565b60005b9050808303838214610d0f57610d0f8a8a84846139d7565b50505090910395945050505050565b6000610d80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613a9f9092919063ffffffff16565b9050805160001480610da1575080806020019051810190610da19190615178565b610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ca3565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408082018390526101608201839052610180820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610f0a576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014610f5e576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50959695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146110db576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff8116301480159061110957306101208601525b600061014086015280156111bc57600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505050505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916112199160040190815260200190565b600060405180830381600087803b15801561123357600080fd5b505af1158015611247573d6000803e3d6000fd5b5096979650505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff1661130f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff90911603611404576113ff816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b6114e0565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156114c057600080fd5b505af11580156114d4573d6000803e3d6000fd5b50503061012086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161158657905b606083015161010086015161ffff61271092830316918402908202908101908302816115b4576115b461510e565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e9190615208565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161168457876101000151611687565b60005b866040015161169757600061169e565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561170857600080fd5b505af115801561171c573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b49190615208565b9050818110806117d257506101008701516117cf9083615221565b81105b15611809576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915260006118ad8480516001018051915290565b60ff16905060008361010001519050600060028310156118f9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611b84576000611914600188614f63565b82106119205785611951565b6127106119338b80516002018051915290565b61ffff168a610100015161194791906150f7565b611951919061513d565b90508581111561198d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119978187614f63565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261012080820183815261014080840185815261016085018690526101808501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d015116909152909650611a368b82610a5a565b9050806101600151600103611a77576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611a945780610120015193508061014001519450611b68565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614611afe576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614611b68576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100810151611b789087615221565b955050506001016118ff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152611c4660405180606001604052806060815260200160608152602001606081525090565b6000611c588580516001018051915290565b60ff169050611c68816001615221565b67ffffffffffffffff811115611c8057611c806148ad565b604051908082528060200260200182016040528015611ca9578160200160208202803683370190505b508083526101408501518151909190600090611cc757611cc7615234565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b81811015611d6057855160140180519087528351611d23836001615221565b81518110611d3357611d33615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611d04565b50611d6b8582613ab6565b6020830152611d7a8582613b58565b6040830152815180516000919083908110611d9757611d97615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e319190615208565b90506000611e52846040015187610100015186600001518760200151613be1565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff1603611ee457611edf8460200151600081518110611ea657611ea6615234565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b611fe3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c78516929190600090611f4357611f43615234565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b8152600401611fa9949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015611fc357600080fd5b505af1158015611fd7573d6000803e3d6000fd5b50503061012089015250505b60005b838110156121e7576000611ffb826001615221565b905060008660000151828151811061201557612015615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168760000151848151811061204957612049615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612073576000612076565b60015b90506000600288600001515161208c9190614f63565b841061209857306120b7565b876020015183815181106120ae576120ae615234565b60200260200101515b9050876020015184815181106120cf576120cf615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836121165786858151811061210957612109615234565b6020026020010151612119565b60005b84612125576000612140565b87868151811061213757612137615234565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156121c057600080fd5b505af11580156121d4573d6000803e3d6000fd5b505060019095019450611fe69350505050565b5060008460000151848151811061220057612200615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229a9190615208565b905081600183516122ab9190614f63565b815181106122bb576122bb615234565b602002602001015187610100018181525050828110806122e957506101008701516122e69084615221565b81105b15612320576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845180518590811061233457612334615234565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff90811660208301526101408401511661247a576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156124e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250c9190615208565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff161090506125a86040518060600160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff16815250613e16565b801561268c5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561264f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126739190615263565b9150508061268090615287565b61010087015250612774565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561273c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127609190615263565b50905061276c81615287565b610100870152505b61277c613f7f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e9190615208565b90508281108061282c57506101008601516128299084615221565b81105b15612863576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261291e60405180606001604052806060815260200160608152602001606081525090565b60006129308580516001018051915290565b60ff16905061293f8582613ab6565b825261294b8582613ab6565b60208301528151600090612960600184614f63565b8151811061297057612970615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156129eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0f9190615208565b905060005b83811015612cd75760008115612a4e578551612a31600184614f63565b81518110612a4157612a41615234565b6020026020010151612a55565b8761014001515b905085600001518281518110612a6d57612a6d615234565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516060810182526101008d015181526101208d01518416948101949094529184169183018290521190612ace90613e16565b82600003612ade57306101208a01525b600087602001518481518110612af657612af6615234565b602002602001015190508115612be0576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc79190615263565b91505080612bd490615287565b6101008c015250612cc4565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb09190615263565b509050612cbc81615287565b6101008c0152505b612ccc613f7f565b505050600101612a14565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6e9190615208565b905081811080612d8c5750610100870151612d899083615221565b81105b15612dc3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff9283161592918216159130911614613006577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612fe657600080fd5b505af1158015612ffa573d6000803e3d6000fd5b50503061012088015250505b6000816130a35783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561307a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309e9190615208565b6130a5565b475b9050826130e5576130e5846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff16613fdf9092919063ffffffff16565b61312a84608001518560a0015186602001518661310357600061310a565b8961010001515b886040015189606001518c610100015160008b8061312557508a5b6140d5565b6000826131c75784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561319e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c29190615208565b6131c9565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506131f38282614f63565b61010088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526132a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613431576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff166101008201528451602080820180519092010186526101208201526040516133fc9082906020016152bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613543578060800151516000036134a5578251610140840151602085015161010086015161349e93929161ffff169080610c65565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3866080015187610100015160405161353a929190918252602082015260400190565b60405180910390a45b6135558360a001518460c00151610c37565b8361010001511015613593576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff91821691161561377f5761012084015173ffffffffffffffffffffffffffffffffffffffff1630146136d1577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156136b157600080fd5b505af11580156136c5573d6000803e3d6000fd5b50503061012087015250505b61377f8260800151516000146136e75781613756565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613732573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061375691906152d2565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff169190613fdf565b6001610160850152608082015151156137985780613807565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380791906152d2565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff16146138665785610180015161387c565b85610180015186610100015161387c9190615221565b8451602086015160408701516101008a015160c08b01513091906138a1908290610c37565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c6080015151116138e7578d604001516138e9565b305b604051602001613924919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b16835261399499989796959493926004016152ef565b6000604051808303818588803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b5050600061018088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060613aae84846000856145d1565b949350505050565b60608167ffffffffffffffff811115613ad157613ad16148ad565b604051908082528060200260200182016040528015613afa578160200160208202803683370190505b50905060005b82811015613b515783516014018051908552828281518110613b2457613b24615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613b00565b5092915050565b60608167ffffffffffffffff811115613b7357613b736148ad565b604051908082528060200260200182016040528015613b9c578160200160208202803683370190505b50905060005b82811015613b515783516002018051908552828281518110613bc657613bc6615234565b61ffff90921660209283029190910190910152600101613ba2565b805182516060919067ffffffffffffffff811115613c0157613c016148ad565b604051908082528060200260200182016040528015613c2a578160200160208202803683370190505b5091508482600081518110613c4157613c41615234565b60200260200101818152505060005b81811015613e0c576000858281518110613c6c57613c6c615234565b60200260200101519050600086836001613c869190615221565b81518110613c9657613c96615234565b602002602001015190506000898481518110613cb457613cb4615234565b6020026020010151612710613cc991906150dc565b61ffff169050600080888681518110613ce457613ce4615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d5a91906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115613db557905b828b0282612710020181848d020281613dd057613dd061510e565b049a508a88613de0886001615221565b81518110613df057613df0615234565b6020908102919091010152505060019093019250613c50915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613e74576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613fdd576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261406b84826146ea565b6140cf5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526140c59085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109d3565b6140cf8482610d1e565b50505050565b8860ff1660010361420357871561418e576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561417057600080fd5b505af1158015614184573d6000803e3d6000fd5b50505050506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614157565b8860ff166002036143435787156142ce576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156142a3573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906142c89190615208565b506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614285565b8860ff166003036144e45787156143c1576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614285565b801561443b576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614285565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af11580156144c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c89190615208565b8860ff16600403614594578715614527576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614157565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b606082471015614663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ca3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161468c919061539b565b60006040518083038185875af1925050503d80600081146146c9576040519150601f19603f3d011682016040523d82523d6000602084013e6146ce565b606091505b50915091506146df878383876147ab565b979650505050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614714919061539b565b6000604051808303816000865af19150503d8060008114614751576040519150601f19603f3d011682016040523d82523d6000602084013e614756565b606091505b50915091508180156147805750805115806147805750808060200190518101906147809190615178565b80156147a2575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060831561484157825160000361483a5773ffffffffffffffffffffffffffffffffffffffff85163b61483a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca3565b5081613aae565b613aae83838151156148565781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca391906153b7565b61ffff8116811461489a57600080fd5b50565b80356148a88161488a565b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614900576149006148ad565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561494d5761494d6148ad565b604052919050565b600067ffffffffffffffff82111561496f5761496f6148ad565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149ac57600080fd5b81356149bf6149ba82614955565b614906565b8181528460208386010111156149d457600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461489a57600080fd5b80356148a8816149f1565b60008060008060008060c08789031215614a3757600080fd5b8635614a428161488a565b9550602087013567ffffffffffffffff80821115614a5f57600080fd5b614a6b8a838b0161499b565b96506040890135955060608901359150614a84826149f1565b9093506080880135925060a08801359080821115614aa157600080fd5b50614aae89828a0161499b565b9150509295509295509295565b65ffffffffffff8116811461489a57600080fd5b80356148a881614abb565b600060408284031215614aec57600080fd5b50919050565b60008060408385031215614b0557600080fd5b823567ffffffffffffffff80821115614b1d57600080fd5b908401906101408287031215614b3257600080fd5b614b3a6148dc565b614b4383614a13565b8152614b516020840161489d565b6020820152614b626040840161489d565b6040820152614b7360608401614a13565b6060820152614b8460808401614a13565b6080820152614b9560a08401614a13565b60a082015260c083013560c082015260e083013560e0820152610100614bbc818501614acf565b908201526101208381013583811115614bd457600080fd5b614be08982870161499b565b828401525050809450506020850135915080821115614bfe57600080fd5b50614c0b85828601614ada565b9150509250929050565b80516148a8816149f1565b80516148a88161488a565b80516148a881614abb565b60005b83811015614c51578181015183820152602001614c39565b50506000910152565b600082601f830112614c6b57600080fd5b8151614c796149ba82614955565b818152846020838601011115614c8e57600080fd5b613aae826020830160208701614c36565b600060208284031215614cb157600080fd5b815167ffffffffffffffff80821115614cc957600080fd5b908301906101408286031215614cde57600080fd5b614ce66148dc565b614cef83614c15565b8152614cfd60208401614c20565b6020820152614d0e60408401614c20565b6040820152614d1f60608401614c15565b6060820152614d3060808401614c15565b6080820152614d4160a08401614c15565b60a082015260c083015160c082015260e083015160e0820152610100614d68818501614c2b565b908201526101208381015183811115614d8057600080fd5b614d8c88828701614c5a565b918301919091525095945050505050565b60008151808452614db5816020860160208601614c36565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006101406020830151614e1b602086018261ffff169052565b506040830151614e31604086018261ffff169052565b506060830151614e59606086018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151614e81608086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614ea960a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015160c085015260e083015160e085015261010080840151614ed88287018265ffffffffffff169052565b5050610120808401518282870152614ef283870182614d9d565b9695505050505050565b604081526000614f0f6040830185614de7565b828103602084015283518152602084015160406020830152614ef26040830182614d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c3157610c31614f34565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614fab57600080fd5b83018035915067ffffffffffffffff821115614fc657600080fd5b602001915036819003821315614fdb57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150d5576150d5614f34565b5060010190565b61ffff828116828216039080821115613b5157613b51614f34565b8082028115828204841417610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615173577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561518a57600080fd5b81518015158114610c5e57600080fd5b80516dffffffffffffffffffffffffffff811681146148a857600080fd5b6000806000606084860312156151cd57600080fd5b6151d68461519a565b92506151e46020850161519a565b9150604084015163ffffffff811681146151fd57600080fd5b809150509250925092565b60006020828403121561521a57600080fd5b5051919050565b80820180821115610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561527657600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036152b8576152b8614f34565b5060000390565b602081526000610c5e6020830184614de7565b6000602082840312156152e457600080fd5b8151610c5e816149f1565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615362610180840182614d9d565b905082810360e08401526153768186614d9d565b905082810361010084015261538b8185614d9d565b9c9b505050505050505050505050565b600082516153ad818460208701614c36565b9190910192915050565b602081526000610c5e6020830184614d9d56fea26469706673582212204eecdc76d361ea4a608ec1291a66f39b61f591d844e03c8f4164adb5e8c419c464736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c8063ab8236f31461002e578063dc7b39db14610050575b600080fd5b34801561003a57600080fd5b5061004e610049366004614a1e565b610063565b005b61004e61005e366004614af2565b61036f565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff1633146100d6576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461012a576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906101409190614c9f565b608081015190915073ffffffffffffffffffffffffffffffffffffffff1661016757600094505b3063dc7b39db73ffffffffffffffffffffffffffffffffffffffff871615610190576000610192565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff168152602001856101200151815250604051806040016040528060008152602001604051806020016040528060008152508152506040518463ffffffff1660e01b81526004016102a4929190614efc565b6000604051808303818588803b1580156102bd57600080fd5b505af1935050505080156102cf575060015b6103655773ffffffffffffffffffffffffffffffffffffffff851661033e57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610338573d6000803e3d6000fd5b50610365565b60608101516103659073ffffffffffffffffffffffffffffffffffffffff87169086610981565b5050505050505050565b81610100015165ffffffffffff164211156103b6576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152825173ffffffffffffffffffffffffffffffffffffffff908116825260208085015161ffff9081169184019190915260408086018051831660c08087019182526060808a01518716948801949094526080808a01805188169589019590955290890180519188019190915260e0808a015160a0890152925190941690526101008088015165ffffffffffff169186019190915291519184019190915280518216610140840152511661052a578260c00151341015610509576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08301516105189034614f63565b610180820152306101208201526106bd565b336101208201523461018082015260006105476020840184614f76565b905011156106bd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff1681525085806020019061066b9190614f76565b6040518563ffffffff1660e01b815260040161068a9493929190614fe2565b600060405180830381600087803b1580156106a457600080fd5b505af11580156106b8573d6000803e3d6000fd5b505050505b60006106e2846101200151604080518082019091528181528151909101602082015290565b90506106ee8183610a5a565b61010081015161014082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610755576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107678660e001518760400151610c37565b8210156107a0576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361016001516001036107b557505050505050565b6107d686600001518760a00151886020015161ffff168960e0015186610c65565b915081600003610812576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661087d57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610877573d6000803e3d6000fd5b506108a4565b60608601516108a49073ffffffffffffffffffffffffffffffffffffffff83169084610981565b610180840151156108e257610180840151604051339180156108fc02916000818181858888f193505050501580156108e0573d6000803e3d6000fd5b505b8560a0015173ffffffffffffffffffffffffffffffffffffffff16866080015173ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c0015186604051610971929190918252602082015260400190565b60405180910390a4505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610d1e565b505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526000610ad58480516001018051915290565b60ff16905060005b81811015610c2b576000610af78680516001018051915290565b60ff16905060018103610b1457610b0d85610e2d565b9450610c18565b60028103610b2557610b0d85610ff5565b60038103610b3757610b0d8686611254565b60048103610b4957610b0d8686611832565b60058103610b5b57610b0d8686611bb9565b60068103610b6d57610b0d8686612367565b60078103610b7f57610b0d8686612891565b60088103610b9157610b0d8686612dcf565b60098103610be657610ba4600184614f63565b8214610bdc576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b0d8686613205565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5080610c23816150a4565b915050610add565b50829150505b92915050565b6000612710610c4683826150dc565b610c549061ffff16856150f7565b610c5e919061513d565b9392505050565b60006107d0841115610cac576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610cbe575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610cf45760646032840204610cf7565b60005b9050808303838214610d0f57610d0f8a8a84846139d7565b50505090910395945050505050565b6000610d80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613a9f9092919063ffffffff16565b9050805160001480610da1575080806020019051810190610da19190615178565b610a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ca3565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408082018390526101608201839052610180820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610f0a576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014610f5e576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50959695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146110db576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff8116301480159061110957306101208601525b600061014086015280156111bc57600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505050505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916112199160040190815260200190565b600060405180830381600087803b15801561123357600080fd5b505af1158015611247573d6000803e3d6000fd5b5096979650505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff1661130f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff90911603611404576113ff816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b6114e0565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156114c057600080fd5b505af11580156114d4573d6000803e3d6000fd5b50503061012086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155691906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161158657905b606083015161010086015161ffff61271092830316918402908202908101908302816115b4576115b461510e565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e9190615208565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161168457876101000151611687565b60005b866040015161169757600061169e565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561170857600080fd5b505af115801561171c573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b49190615208565b9050818110806117d257506101008701516117cf9083615221565b81105b15611809576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915260006118ad8480516001018051915290565b60ff16905060008361010001519050600060028310156118f9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611b84576000611914600188614f63565b82106119205785611951565b6127106119338b80516002018051915290565b61ffff168a610100015161194791906150f7565b611951919061513d565b90508581111561198d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119978187614f63565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261012080820183815261014080840185815261016085018690526101808501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d015116909152909650611a368b82610a5a565b9050806101600151600103611a77576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611a945780610120015193508061014001519450611b68565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614611afe576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614611b68576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100810151611b789087615221565b955050506001016118ff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101829052610180810191909152611c4660405180606001604052806060815260200160608152602001606081525090565b6000611c588580516001018051915290565b60ff169050611c68816001615221565b67ffffffffffffffff811115611c8057611c806148ad565b604051908082528060200260200182016040528015611ca9578160200160208202803683370190505b508083526101408501518151909190600090611cc757611cc7615234565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b81811015611d6057855160140180519087528351611d23836001615221565b81518110611d3357611d33615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101611d04565b50611d6b8582613ab6565b6020830152611d7a8582613b58565b6040830152815180516000919083908110611d9757611d97615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e319190615208565b90506000611e52846040015187610100015186600001518760200151613be1565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff1603611ee457611edf8460200151600081518110611ea657611ea6615234565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166109819092919063ffffffff16565b611fe3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c78516929190600090611f4357611f43615234565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b8152600401611fa9949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015611fc357600080fd5b505af1158015611fd7573d6000803e3d6000fd5b50503061012089015250505b60005b838110156121e7576000611ffb826001615221565b905060008660000151828151811061201557612015615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168760000151848151811061204957612049615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612073576000612076565b60015b90506000600288600001515161208c9190614f63565b841061209857306120b7565b876020015183815181106120ae576120ae615234565b60200260200101515b9050876020015184815181106120cf576120cf615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836121165786858151811061210957612109615234565b6020026020010151612119565b60005b84612125576000612140565b87868151811061213757612137615234565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b1580156121c057600080fd5b505af11580156121d4573d6000803e3d6000fd5b505060019095019450611fe69350505050565b5060008460000151848151811061220057612200615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229a9190615208565b905081600183516122ab9190614f63565b815181106122bb576122bb615234565b602002602001015187610100018181525050828110806122e957506101008701516122e69084615221565b81105b15612320576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845180518590811061233457612334615234565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff90811660208301526101408401511661247a576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156124e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250c9190615208565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff161090506125a86040518060600160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff16815250613e16565b801561268c5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561264f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126739190615263565b9150508061268090615287565b61010087015250612774565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561273c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127609190615263565b50905061276c81615287565b610100870152505b61277c613f7f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e9190615208565b90508281108061282c57506101008601516128299084615221565b81105b15612863576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081019190915261291e60405180606001604052806060815260200160608152602001606081525090565b60006129308580516001018051915290565b60ff16905061293f8582613ab6565b825261294b8582613ab6565b60208301528151600090612960600184614f63565b8151811061297057612970615234565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156129eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0f9190615208565b905060005b83811015612cd75760008115612a4e578551612a31600184614f63565b81518110612a4157612a41615234565b6020026020010151612a55565b8761014001515b905085600001518281518110612a6d57612a6d615234565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516060810182526101008d015181526101208d01518416948101949094529184169183018290521190612ace90613e16565b82600003612ade57306101208a01525b600087602001518481518110612af657612af6615234565b602002602001015190508115612be0576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc79190615263565b91505080612bd490615287565b6101008c015250612cc4565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612c8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb09190615263565b509050612cbc81615287565b6101008c0152505b612ccc613f7f565b505050600101612a14565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6e9190615208565b905081811080612d8c5750610100870151612d899083615221565b81105b15612dc3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff9283161592918216159130911614613006577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612fe657600080fd5b505af1158015612ffa573d6000803e3d6000fd5b50503061012088015250505b6000816130a35783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561307a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309e9190615208565b6130a5565b475b9050826130e5576130e5846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff16613fdf9092919063ffffffff16565b61312a84608001518560a0015186602001518661310357600061310a565b8961010001515b886040015189606001518c610100015160008b8061312557508a5b6140d5565b6000826131c75784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561319e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c29190615208565b6131c9565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506131f38282614f63565b61010088015250949695505050505050565b604080516101a081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808101919091526132a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613431576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff166101008201528451602080820180519092010186526101208201526040516133fc9082906020016152bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613543578060800151516000036134a5578251610140840151602085015161010086015161349e93929161ffff169080610c65565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f3866080015187610100015160405161353a929190918252602082015260400190565b60405180910390a45b6135558360a001518460c00151610c37565b8361010001511015613593576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff91821691161561377f5761012084015173ffffffffffffffffffffffffffffffffffffffff1630146136d1577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156136b157600080fd5b505af11580156136c5573d6000803e3d6000fd5b50503061012087015250505b61377f8260800151516000146136e75781613756565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613732573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061375691906152d2565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff169190613fdf565b6001610160850152608082015151156137985780613807565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380791906152d2565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff16146138665785610180015161387c565b85610180015186610100015161387c9190615221565b8451602086015160408701516101008a015160c08b01513091906138a1908290610c37565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c6080015151116138e7578d604001516138e9565b305b604051602001613924919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b16835261399499989796959493926004016152ef565b6000604051808303818588803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b5050600061018088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b6060613aae84846000856145d1565b949350505050565b60608167ffffffffffffffff811115613ad157613ad16148ad565b604051908082528060200260200182016040528015613afa578160200160208202803683370190505b50905060005b82811015613b515783516014018051908552828281518110613b2457613b24615234565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613b00565b5092915050565b60608167ffffffffffffffff811115613b7357613b736148ad565b604051908082528060200260200182016040528015613b9c578160200160208202803683370190505b50905060005b82811015613b515783516002018051908552828281518110613bc657613bc6615234565b61ffff90921660209283029190910190910152600101613ba2565b805182516060919067ffffffffffffffff811115613c0157613c016148ad565b604051908082528060200260200182016040528015613c2a578160200160208202803683370190505b5091508482600081518110613c4157613c41615234565b60200260200101818152505060005b81811015613e0c576000858281518110613c6c57613c6c615234565b60200260200101519050600086836001613c869190615221565b81518110613c9657613c96615234565b602002602001015190506000898481518110613cb457613cb4615234565b6020026020010151612710613cc991906150dc565b61ffff169050600080888681518110613ce457613ce4615234565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d5a91906151b8565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115613db557905b828b0282612710020181848d020281613dd057613dd061510e565b049a508a88613de0886001615221565b81518110613df057613df0615234565b6020908102919091010152505060019093019250613c50915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613e74576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613fdd576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261406b84826146ea565b6140cf5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526140c59085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109d3565b6140cf8482610d1e565b50505050565b8860ff1660010361420357871561418e576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b15801561417057600080fd5b505af1158015614184573d6000803e3d6000fd5b50505050506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614157565b8860ff166002036143435787156142ce576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af11580156142a3573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906142c89190615208565b506145c6565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614285565b8860ff166003036144e45787156143c1576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614285565b801561443b576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614285565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af11580156144c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c89190615208565b8860ff16600403614594578715614527576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614157565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b606082471015614663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610ca3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161468c919061539b565b60006040518083038185875af1925050503d80600081146146c9576040519150601f19603f3d011682016040523d82523d6000602084013e6146ce565b606091505b50915091506146df878383876147ab565b979650505050505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614714919061539b565b6000604051808303816000865af19150503d8060008114614751576040519150601f19603f3d011682016040523d82523d6000602084013e614756565b606091505b50915091508180156147805750805115806147805750808060200190518101906147809190615178565b80156147a2575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6060831561484157825160000361483a5773ffffffffffffffffffffffffffffffffffffffff85163b61483a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca3565b5081613aae565b613aae83838151156148565781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca391906153b7565b61ffff8116811461489a57600080fd5b50565b80356148a88161488a565b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614900576149006148ad565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561494d5761494d6148ad565b604052919050565b600067ffffffffffffffff82111561496f5761496f6148ad565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126149ac57600080fd5b81356149bf6149ba82614955565b614906565b8181528460208386010111156149d457600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461489a57600080fd5b80356148a8816149f1565b60008060008060008060c08789031215614a3757600080fd5b8635614a428161488a565b9550602087013567ffffffffffffffff80821115614a5f57600080fd5b614a6b8a838b0161499b565b96506040890135955060608901359150614a84826149f1565b9093506080880135925060a08801359080821115614aa157600080fd5b50614aae89828a0161499b565b9150509295509295509295565b65ffffffffffff8116811461489a57600080fd5b80356148a881614abb565b600060408284031215614aec57600080fd5b50919050565b60008060408385031215614b0557600080fd5b823567ffffffffffffffff80821115614b1d57600080fd5b908401906101408287031215614b3257600080fd5b614b3a6148dc565b614b4383614a13565b8152614b516020840161489d565b6020820152614b626040840161489d565b6040820152614b7360608401614a13565b6060820152614b8460808401614a13565b6080820152614b9560a08401614a13565b60a082015260c083013560c082015260e083013560e0820152610100614bbc818501614acf565b908201526101208381013583811115614bd457600080fd5b614be08982870161499b565b828401525050809450506020850135915080821115614bfe57600080fd5b50614c0b85828601614ada565b9150509250929050565b80516148a8816149f1565b80516148a88161488a565b80516148a881614abb565b60005b83811015614c51578181015183820152602001614c39565b50506000910152565b600082601f830112614c6b57600080fd5b8151614c796149ba82614955565b818152846020838601011115614c8e57600080fd5b613aae826020830160208701614c36565b600060208284031215614cb157600080fd5b815167ffffffffffffffff80821115614cc957600080fd5b908301906101408286031215614cde57600080fd5b614ce66148dc565b614cef83614c15565b8152614cfd60208401614c20565b6020820152614d0e60408401614c20565b6040820152614d1f60608401614c15565b6060820152614d3060808401614c15565b6080820152614d4160a08401614c15565b60a082015260c083015160c082015260e083015160e0820152610100614d68818501614c2b565b908201526101208381015183811115614d8057600080fd5b614d8c88828701614c5a565b918301919091525095945050505050565b60008151808452614db5816020860160208601614c36565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b805173ffffffffffffffffffffffffffffffffffffffff16825260006101406020830151614e1b602086018261ffff169052565b506040830151614e31604086018261ffff169052565b506060830151614e59606086018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151614e81608086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060a0830151614ea960a086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060c083015160c085015260e083015160e085015261010080840151614ed88287018265ffffffffffff169052565b5050610120808401518282870152614ef283870182614d9d565b9695505050505050565b604081526000614f0f6040830185614de7565b828103602084015283518152602084015160406020830152614ef26040830182614d9d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c3157610c31614f34565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614fab57600080fd5b83018035915067ffffffffffffffff821115614fc657600080fd5b602001915036819003821315614fdb57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150d5576150d5614f34565b5060010190565b61ffff828116828216039080821115613b5157613b51614f34565b8082028115828204841417610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615173577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561518a57600080fd5b81518015158114610c5e57600080fd5b80516dffffffffffffffffffffffffffff811681146148a857600080fd5b6000806000606084860312156151cd57600080fd5b6151d68461519a565b92506151e46020850161519a565b9150604084015163ffffffff811681146151fd57600080fd5b809150509250925092565b60006020828403121561521a57600080fd5b5051919050565b80820180821115610c3157610c31614f34565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561527657600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036152b8576152b8614f34565b5060000390565b602081526000610c5e6020830184614de7565b6000602082840312156152e457600080fd5b8151610c5e816149f1565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615362610180840182614d9d565b905082810360e08401526153768186614d9d565b905082810361010084015261538b8185614d9d565b9c9b505050505050505050505050565b600082516153ad818460208701614c36565b9190910192915050565b602081526000610c5e6020830184614d9d56fea26469706673582212204eecdc76d361ea4a608ec1291a66f39b61f591d844e03c8f4164adb5e8c419c464736f6c63430008130033", + "numDeployments": 13, + "solcInputHash": "c6735d71c8937120ee5b82bc32fb5df3", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxFeeBps\",\"type\":\"uint256\"}],\"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\":\"InvalidSgReceiveSrcAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSgReceiverSender\",\"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\":[],\"name\":\"UnhandledPoolKind\",\"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\":\"partnerFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"name\":\"Fee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"name\":\"Warp\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"bytes\",\"name\":\"_srcAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountLD\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sgReceive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"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\":\"warpLinkEngagePermit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint256)\":[{\"notice\":\"The swap fee is over the maximum allowed\"},{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{\"sgReceive(uint16,bytes,uint256,address,uint256,bytes)\":{\"notice\":\"Cross-chain callback from Stargate The tokens have already been received by this contract, `t.payer` is set to this contract before `sgReceive` is called by the router. The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the same message more than once. The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the Stargate composer be compromised, an attacker can drain this contract. If the payload can not be decoded, tokens are left in this contract. If execution runs out of gas, tokens are left in this contract. If an error occurs during engage, such as insufficient output amount, tokens are refunded to the recipient. See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\"}},\"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\"},\"@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 {LibStarVault} from '../libraries/LibStarVault.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';\\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\\n bytes payload;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n address paramTokenIn;\\n uint256 paramAmountIn;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint48 paramDeadline;\\n uint256 amount;\\n address payer;\\n address token;\\n /**\\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\\n */\\n uint256 usePermit;\\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 if (t.usePermit == 1) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\\n }\\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 if (t.usePermit == 1) {\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\\n }\\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 if (t.usePermit == 1) {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(\\n t.payer,\\n params.pools[0],\\n (uint160)(t.amount),\\n t.token\\n );\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\\n }\\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({\\n payer: t.payer,\\n token: t.token,\\n amount: t.amount,\\n usePermit: t.usePermit\\n })\\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({\\n payer: t.payer,\\n token: tokenIn,\\n amount: t.amount,\\n usePermit: t.usePermit\\n })\\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 if (t.usePermit == 1) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\\n }\\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 useEth: isFromEth || isToEth,\\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 * Cross-chain callback from Stargate\\n *\\n * The tokens have already been received by this contract, `t.payer` is set to this contract\\n * before `sgReceive` is called by the router.\\n *\\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\\n * same message more than once.\\n *\\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\\n * Stargate composer be compromised, an attacker can drain this contract.\\n *\\n * If the payload can not be decoded, tokens are left in this contract.\\n * If execution runs out of gas, tokens are left in this contract.\\n *\\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\\n * to the recipient.\\n *\\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\\n */\\n function sgReceive(\\n uint16, // _srcChainId\\n bytes memory _srcAddress,\\n uint256, // _nonce\\n address _token,\\n uint256 amountLD,\\n bytes memory payload\\n ) external {\\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\\n revert InvalidSgReceiverSender();\\n }\\n\\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\\n // From https://ethereum.stackexchange.com/a/50528\\n address srcAddress;\\n\\n assembly {\\n srcAddress := mload(add(_srcAddress, 20))\\n }\\n\\n if (srcAddress != address(this)) {\\n // NOTE: This assumes that this contract is deployed at the same address on every chain\\n revert InvalidSgReceiveSrcAddress();\\n }\\n\\n Params memory params = abi.decode(payload, (Params));\\n\\n if (params.tokenIn == address(0)) {\\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\\n // otherwise because `_token` may be different on this chain\\n _token = address(0);\\n }\\n\\n try\\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\\n Params({\\n partner: params.partner,\\n feeBps: params.feeBps,\\n slippageBps: params.slippageBps,\\n recipient: params.recipient,\\n tokenIn: _token,\\n tokenOut: params.tokenOut,\\n amountIn: amountLD,\\n amountOut: params.amountOut,\\n deadline: params.deadline,\\n commands: params.commands\\n })\\n )\\n {} catch {\\n // Refund tokens to the recipient\\n if (_token == address(0)) {\\n payable(params.recipient).transfer(amountLD);\\n } else {\\n IERC20(_token).safeTransfer(params.recipient, amountLD);\\n }\\n }\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\\n * in this function.\\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 * - dstGasForCall (uint32)\\n * - tokenOut (address) when `dstGasForCall` > 0\\n * - amountOut (uint256) when `dstGasForCall` > 0\\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n params.dstGasForCall = stream.readUint32();\\n\\n if (params.dstGasForCall > 0) {\\n // NOTE: `amountIn` is left as zero\\n Params memory destParams;\\n destParams.partner = t.paramPartner;\\n destParams.feeBps = t.paramFeeBps;\\n destParams.slippageBps = t.paramSlippageBps;\\n destParams.recipient = t.paramRecipient;\\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\\n // the same address as on this chain\\n destParams.tokenIn = t.token;\\n destParams.tokenOut = stream.readAddress();\\n destParams.amountOut = stream.readUint256();\\n destParams.deadline = t.paramDeadline;\\n destParams.commands = stream.readBytes();\\n params.payload = abi.encode(destParams);\\n }\\n\\n if (t.token != t.paramTokenIn) {\\n if (params.payload.length == 0) {\\n // If the tokens are being delivered directly to the recipient without a second\\n // WarpLink engage, the fee is charged on this chain\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibStarVault.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n }\\n\\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\\n\\n if (t.token != address(0)) {\\n if (t.payer != address(this)) {\\n if (t.usePermit == 1) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(\\n t.payer,\\n address(this),\\n (uint160)(t.amount),\\n t.token\\n );\\n } else {\\n // NOTE: `t.usePermit` is left as 1\\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\\n }\\n\\n // Update the payer to this contract\\n // TODO: Is this value ever read?\\n t.payer = address(this);\\n }\\n\\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\\n IERC20(t.token).forceApprove(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\\n t.amount\\n );\\n }\\n\\n t.jumped = 1;\\n\\n // Swap on the composer if there is a payload, else the router\\n IStargateRouter(\\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\\n ).swap{\\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\\n }({\\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\\n // more on the other chain. It also assumes the tokens are of nearly equal value\\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: params.dstGasForCall,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n // NOTE: This assumes the contract is deployed at the same address on every chain.\\n // If this is not the case, a new param needs to be added with the next WarpLink address\\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\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\\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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n\\n function warpLinkEngagePermit(\\n Params calldata params,\\n PermitParams calldata permit\\n ) external payable {\\n TransientState memory t;\\n t.paramPartner = params.partner;\\n t.paramFeeBps = params.feeBps;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramRecipient = params.recipient;\\n t.paramTokenIn = params.tokenIn;\\n t.paramAmountIn = params.amountIn;\\n t.paramAmountOut = params.amountOut;\\n t.paramSlippageBps = params.slippageBps;\\n t.paramDeadline = params.deadline;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.usePermit = 1;\\n\\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 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.jumped == 1) {\\n // The coins have jumped away from this chain. Fees are colelcted before\\n // the jump or on the other chain.\\n //\\n // `t.nativeValueRemaining` is not checked since it should be zero\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibStarVault.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert InsufficientOutputAmount();\\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 if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\\n }\\n}\\n\",\"keccak256\":\"0xafd9df86ea5bc03ea83d33890bbbe7e383f84bec96e5b67dd99e7d717bc9bcb3\",\"license\":\"MIT\"},\"contracts/interfaces/ILibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibCurve {\\n error UnhandledPoolKind();\\n}\\n\",\"keccak256\":\"0xbc06582fb299db2a9174bcee01d6ff8ef611dfd92cbecc9b475f515acf3af45b\",\"license\":\"MIT\"},\"contracts/interfaces/ILibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n}\\n\",\"keccak256\":\"0xd19e560bc438be0ce218fa8f907038c5afca7b742d11af65e7892585227969e1\",\"license\":\"MIT\"},\"contracts/interfaces/ILibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n}\\n\",\"keccak256\":\"0x8f4ef11af715b9c39c44879ea04310cf0bc74e35cfa1b005fd17a3198880246a\",\"license\":\"MIT\"},\"contracts/interfaces/ILibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface ILibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n}\\n\",\"keccak256\":\"0x0ccca1960a2a145b0b26c8c0c5974a883f9a2f909556f5a539222e3cb59cfbaa\",\"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';\\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\\n\\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\\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 error InvalidSgReceiverSender();\\n error InvalidSgReceiveSrcAddress();\\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 calldata params) external payable;\\n\\n function warpLinkEngagePermit(\\n Params calldata params,\\n PermitParams calldata permit\\n ) external payable;\\n}\\n\",\"keccak256\":\"0x0eff4788d9f45d72b6a05f34f1e8236a6f9d76a4778396d9a53c66ec04ebf726\",\"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(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy,\\n bool use_eth\\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\\n// Kind 4, uint256s with no return value\\n// Example v0.2.15, \\\"Pool for USDT/BTC/ETH or similar\\\"\\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\\ninterface ICurvePoolKind4 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\",\"keccak256\":\"0xa820ad027992cf16e3a71318c38b2f30ebaeb197c82f9d7fdc3dffd6928e98f5\",\"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/IStargateComposer.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\nimport {IStargateRouter} from './IStargateRouter.sol';\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateComposer is IStargateRouter {\\n function stargateRouter() external view returns (address);\\n}\\n\",\"keccak256\":\"0x91f0c36063f0c5b9f5a041ed146bb50850e504127cf6400e9250fcee665de984\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IStargateReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\n\\ninterface IStargateReceiver {\\n function sgReceive(\\n uint16 _srcChainId, // the remote chainId sending the tokens\\n bytes memory _srcAddress, // the remote Bridge address\\n uint256 _nonce,\\n address _token, // the token contract on the local chain\\n uint256 amountLD, // the qty of local _token contract tokens\\n bytes memory payload\\n ) external;\\n}\\n\",\"keccak256\":\"0x7fd06c09139156a4f09a77eac28e453a1d2041a8cf01a108fc875c65192cb637\",\"license\":\"BUSL-1.1\"},\"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, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibCurve\\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 bool useEth\\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 if (useEth) {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\\n } else {\\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else if (kind == 4) {\\n if (underlying) {\\n revert UnhandledPoolKind();\\n } else {\\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3800d83c9e2afba4b7baf4f4f5134d93c41b1100faedbc8b3989d0806e2e5003\",\"license\":\"MIT\"},\"contracts/libraries/LibStarVault.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibStarVault\\n */\\nlibrary LibStarVault {\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint256 maxFeeBps);\\n\\n event Fee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 protocolFee\\n );\\n\\n struct State {\\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 uint256 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n /**\\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\\n * removed to save gas.\\n */\\n unchecked {\\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\\n\\n assembly {\\n s.slot := storagePosition\\n }\\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 protocolFee\\n ) internal {\\n State storage s = state();\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit Fee(partner, token, partnerFee, protocolFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint256 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 feeProtocol = feeTotal - feePartner;\\n\\n if (feeProtocol > 0) {\\n registerCollectedFee(partner, token, feePartner, feeProtocol);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x332a4a0e56d3a792a8a6e6ea929ee8c79a5a26de02445a73711228f3966ed948\",\"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\\n/**\\n * NOTE: Events and errors must be copied to ILibUniV3Like\\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 * Whether to use a permit transfer (0 or 1)\\n */\\n uint256 usePermit;\\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\":\"0x8206898e916bdfd9fe9353245bb9e7063ff75879e57e10b3565611040772237f\",\"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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\\n\\n/**\\n * NOTE: Events and errors must be copied to ILibWarp\\n */\\nlibrary LibWarp {\\n event Warp(\\n address indexed partner,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 amountIn,\\n uint256 amountOut\\n );\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateComposer stargateComposer;\\n }\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\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\":\"0x8dc8917472256ee8a304eb2ab94955c873aa3f64d7224ad71f4e8d5af717ca48\",\"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": "0x608060405234801561001057600080fd5b50615c3880620000216000396000f3fe6080604052600436106100345760003560e01c8063a703fc4014610039578063ab8236f31461004e578063dcc455511461006e575b600080fd5b61004c610047366004615184565b610081565b005b34801561005a57600080fd5b5061004c610069366004615368565b6106c6565b61004c61007c366004615405565b6109ac565b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152906100fd9084018461543a565b73ffffffffffffffffffffffffffffffffffffffff1681526101256040840160208501615457565b61ffff16602082015261013e6060840160408501615457565b61ffff1660c0820152610157608084016060850161543a565b73ffffffffffffffffffffffffffffffffffffffff16604082015261018260a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0840135608083015260e084013560a08301526101c490840160408501615457565b61ffff1660c08201526101df61012084016101008501615488565b65ffffffffffff1660e082015260c083013561010082015261020760a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff9081166101408301526001610160830152336101208301819052346101a08401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e08101909152921691632b67b570919080606081018061028a60a08b0160808c0161543a565b73ffffffffffffffffffffffffffffffffffffffff908116825260c08b01351660208201526040016102c46101208b016101008c01615488565b65ffffffffffff908116825289351660209182015290825230908201526040016102f661012089016101008a01615488565b65ffffffffffff16905261030d60208701876154a5565b6040518563ffffffff1660e01b815260040161032c9493929190615511565b600060405180830381600087803b15801561034657600080fd5b505af115801561035a573d6000803e3d6000fd5b5050505060006103ae8480610120019061037491906154a5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f4192505050565b90506103ba8183610f5b565b610100810151610140820151919350906103da60c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043e576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61045b60e08701356104566060890160408a01615457565b611140565b821015610494576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361018001516001036104a957505050505050565b6104e86104b9602088018861543a565b6104c960c0890160a08a0161543a565b6104d960408a0160208b01615457565b61ffff168960e001358661116e565b915081600003610524576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661059a5761054f608087016060880161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610594573d6000803e3d6000fd5b506105cb565b6105cb6105ad608088016060890161543a565b73ffffffffffffffffffffffffffffffffffffffff83169084611227565b6101a084015115610609576101a0840151604051339180156108fc02916000818181858888f19350505050158015610607573d6000803e3d6000fd5b505b61061960c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff1661063f60a088016080890161543a565b73ffffffffffffffffffffffffffffffffffffffff16610662602089018961543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c00135866040516106b6929190918252602082015260400190565b60405180910390a4505050505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461078d576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906107a39190615662565b608081015190915073ffffffffffffffffffffffffffffffffffffffff166107ca57600094505b3063dcc4555173ffffffffffffffffffffffffffffffffffffffff8716156107f35760006107f5565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff1681526020018561012001518152506040518363ffffffff1660e01b81526004016108e191906157aa565b6000604051808303818588803b1580156108fa57600080fd5b505af19350505050801561090c575060015b6109a25773ffffffffffffffffffffffffffffffffffffffff851661097b57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610975573d6000803e3d6000fd5b506109a2565b60608101516109a29073ffffffffffffffffffffffffffffffffffffffff87169086611227565b5050505050505050565b6109be61012082016101008301615488565b65ffffffffffff164211156109ff576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082015290610a7b9083018361543a565b73ffffffffffffffffffffffffffffffffffffffff168152610aa36040830160208401615457565b61ffff166020820152610abc6060830160408401615457565b61ffff1660c0820152610ad5608083016060840161543a565b73ffffffffffffffffffffffffffffffffffffffff166040820152610b0060a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0830135608083015260e083013560a0830152610b4290830160408401615457565b61ffff1660c0820152610b5d61012083016101008401615488565b65ffffffffffff1660e082015260c0820135610100820152610b8560a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff166101408201526000610bb360a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1603610c2c578160c00135341015610c0c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c1a60c0830135346158dc565b6101a082015230610120820152610c3b565b33610120820152346101a08201525b6000610c4e6103746101208501856154a5565b9050610c5a8183610f5b565b61010081015161014082015191935090610c7a60c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cde576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cf660e08601356104566060880160408901615457565b821015610d2f576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836101800151600103610d43575050505050565b610d82610d53602087018761543a565b610d6360c0880160a0890161543a565b610d736040890160208a01615457565b61ffff168860e001358661116e565b915081600003610dbe576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e3457610de9608086016060870161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610e2e573d6000803e3d6000fd5b50610e47565b610e476105ad608087016060880161543a565b6101a084015115610e85576101a0840151604051339180156108fc02916000818181858888f19350505050158015610e83573d6000803e3d6000fd5b505b610e9560c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ebb60a087016080880161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ede602088018861543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38860c0013586604051610f32929190918252602082015260400190565b60405180910390a45050505050565b604080518082019091528181528151909101602082015290565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000610fde8480516001018051915290565b60ff16905060005b818110156111345760006110008680516001018051915290565b60ff1690506001810361101d5761101685611300565b9450611121565b6002810361102e57611016856114d0565b600381036110405761101686866117f2565b60048103611052576110168686611e2a565b600581036110645761101686866121c1565b600681036110765761101686866129e3565b60078103611088576110168686612f20565b6008810361109a576110168686613471565b600981036110ef576110ad6001846158dc565b82146110e5576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61101686866138fd565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061112c816158ef565b915050610fe6565b50829150505b92915050565b600061271061114f8382615927565b61115d9061ffff1685615942565b6111679190615988565b9392505050565b60006107d08411156111b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156111c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156111fd5760646032840204611200565b60005b9050808303838214611218576112188a8a8484614125565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112fb9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526141ed565b505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140808201839052610160820183905261018082018390526101a0820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff16156113e5576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014611439576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b1580156114b057600080fd5b505af11580156114c4573d6000803e3d6000fd5b50959695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146115be576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff811630148015906115ec57306101208601525b6000610140860152801561175a578461016001516001036116b057600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b5050505061175a565b82546101008601516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015611734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175891906159c3565b505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916117b79160040190815260200190565b600060405180830381600087803b1580156117d157600080fd5b505af11580156117e5573d6000803e3d6000fd5b5096979650505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff166118b5576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff909116036119aa576119a5816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b611ad8565b826101600151600103611a90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015611a7357600080fd5b505af1158015611a87573d6000803e3d6000fd5b50505050611ad0565b611ad0836101200151826020015185610100015186610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208401525b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151611b7e57905b606083015161010086015161ffff6127109283031691840290820290810190830281611bac57611bac615959565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c469190615a53565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8560400151611c7c57876101000151611c7f565b60005b8660400151611c8f576000611c96565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015611d0057600080fd5b505af1158015611d14573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190615a53565b905081811080611dca5750610100870151611dc79083615a6c565b81105b15611e01576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000611ead8480516001018051915290565b60ff1690506000836101000151905060006002831015611ef9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561218c576000611f146001886158dc565b8210611f205785611f51565b612710611f338b80516002018051915290565b61ffff168a6101000151611f479190615942565b611f519190615988565b905085811115611f8d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f9781876158dc565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610120808201838152610140808401858152610160850186905261018085018690526101a08501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d01511690915290965061203e8b82610f5b565b905080610180015160010361207f576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361209c5780610120015193508061014001519450612170565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614612106576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614612170576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008101516121809087615a6c565b95505050600101611eff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261225660405180606001604052806060815260200160608152602001606081525090565b60006122688580516001018051915290565b60ff169050612278816001615a6c565b67ffffffffffffffff81111561229057612290615202565b6040519080825280602002602001820160405280156122b9578160200160208202803683370190505b5080835261014085015181519091906000906122d7576122d7615a7f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561237057855160140180519087528351612333836001615a6c565b8151811061234357612343615a7f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612314565b5061237b8582614360565b602083015261238a8582614402565b60408301528151805160009190839081106123a7576123a7615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615a53565b9050600061246284604001518761010001518660000151876020015161448b565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff16036124f4576124ef84602001516000815181106124b6576124b6615a7f565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b61265f565b8561016001516001036125fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061256057612560615a7f565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b81526004016125c6949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b50505050612657565b612657866101200151856020015160008151811061261d5761261d615a7f565b602002602001015188610100015189610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208701525b60005b83811015612863576000612677826001615a6c565b905060008660000151828151811061269157612691615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16876000015184815181106126c5576126c5615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106126ef5760006126f2565b60015b90506000600288600001515161270891906158dc565b84106127145730612733565b8760200151838151811061272a5761272a615a7f565b60200260200101515b90508760200151848151811061274b5761274b615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836127925786858151811061278557612785615a7f565b6020026020010151612795565b60005b846127a15760006127bc565b8786815181106127b3576127b3615a7f565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561283c57600080fd5b505af1158015612850573d6000803e3d6000fd5b5050600190950194506126629350505050565b5060008460000151848151811061287c5761287c615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129169190615a53565b9050816001835161292791906158dc565b8151811061293757612937615a7f565b6020026020010151876101000181815250508281108061296557506101008701516129629084615a6c565b81105b1561299c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518051859081106129b0576129b0615a7f565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015261014084015116612afe576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190615a53565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff16109050612c376040518060800160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018761016001518152506146c0565b8015612d1b5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d029190615aae565b91505080612d0f90615ad2565b61010087015250612e03565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def9190615aae565b509050612dfb81615ad2565b610100870152505b612e0b61484f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615a53565b905082811080612ebb5750610100860151612eb89084615a6c565b81105b15612ef2576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a0810191909152612fb560405180606001604052806060815260200160608152602001606081525090565b6000612fc78580516001018051915290565b60ff169050612fd68582614360565b8252612fe28582614360565b60208301528151600090612ff76001846158dc565b8151811061300757613007615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190615a53565b905060005b8381101561337957600081156130e55785516130c86001846158dc565b815181106130d8576130d8615a7f565b60200260200101516130ec565b8761014001515b90508560000151828151811061310457613104615a7f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516080810182526101008d015181526101208d01518416948101949094529184169183018290526101608b015160608401521190613170906146c0565b8260000361318057306101208a01525b60008760200151848151811061319857613198615a7f565b602002602001015190508115613282576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615aae565b9150508061327690615ad2565b6101008c015250613366565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561332e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133529190615aae565b50905061335e81615ad2565b6101008c0152505b61336e61484f565b5050506001016130ab565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156133ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134109190615a53565b90508181108061342e575061010087015161342b9083615a6c565b81105b15613465576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146136fe578461016001516001036136ba577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561369d57600080fd5b505af11580156136b1573d6000803e3d6000fd5b505050506136f6565b6136f68561012001513087610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208601525b60008161379b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137969190615a53565b61379d565b475b9050826137dd576137dd846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166148af9092919063ffffffff16565b61382284608001518560a001518660200151866137fb576000613802565b8961010001515b886040015189606001518c610100015160008b8061381d57508a5b61499f565b6000826138bf5784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ba9190615a53565b6138c1565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506138eb82826158dc565b61010088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526139a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613b31576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff16610100820152845160208082018051909201018652610120820152604051613afc9082906020016157aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613c4357806080015151600003613ba55782516101408401516020850151610100860151613b9e93929161ffff16908061116e565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38660800151876101000151604051613c3a929190918252602082015260400190565b60405180910390a45b613c558360a001518460c00151611140565b8361010001511015613c93576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff918216911615613ecd5761012084015173ffffffffffffffffffffffffffffffffffffffff163014613e1f57836101600151600103613ddb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015613dbe57600080fd5b505af1158015613dd2573d6000803e3d6000fd5b50505050613e17565b613e178461012001513086610100015187610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208501525b613ecd826080015151600014613e355781613ea4565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea49190615b0a565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff1691906148af565b600161018085015260808201515115613ee65780613f55565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f559190615b0a565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff1614613fb457856101a00151613fca565b856101a00151866101000151613fca9190615a6c565b8451602086015160408701516101008a015160c08b0151309190613fef908290611140565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c608001515111614035578d60400151614037565b305b604051602001614072919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b1683526140e29998979695949392600401615b27565b6000604051808303818588803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b505060006101a088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b600061424f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614e9b9092919063ffffffff16565b905080516000148061427057508080602001905181019061427091906159c3565b6112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016111ac565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261435a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611279565b50505050565b60608167ffffffffffffffff81111561437b5761437b615202565b6040519080825280602002602001820160405280156143a4578160200160208202803683370190505b50905060005b828110156143fb57835160140180519085528282815181106143ce576143ce615a7f565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016143aa565b5092915050565b60608167ffffffffffffffff81111561441d5761441d615202565b604051908082528060200260200182016040528015614446578160200160208202803683370190505b50905060005b828110156143fb578351600201805190855282828151811061447057614470615a7f565b61ffff9092166020928302919091019091015260010161444c565b805182516060919067ffffffffffffffff8111156144ab576144ab615202565b6040519080825280602002602001820160405280156144d4578160200160208202803683370190505b50915084826000815181106144eb576144eb615a7f565b60200260200101818152505060005b818110156146b657600085828151811061451657614516615a7f565b602002602001015190506000868360016145309190615a6c565b8151811061454057614540615a7f565b60200260200101519050600089848151811061455e5761455e615a7f565b60200260200101516127106145739190615927565b61ffff16905060008088868151811061458e5761458e615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156145e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146049190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561465f57905b828b0282612710020181848d02028161467a5761467a615959565b049a508a8861468a886001615a6c565b8151811061469a5761469a615a7f565b60209081029190910101525050600190930192506144fa915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361471e576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036148ad576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261493b8482614eb2565b61435a5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526149959085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611279565b61435a84826141ed565b8860ff16600103614acd578715614a58576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015614a3a57600080fd5b505af1158015614a4e573d6000803e3d6000fd5b5050505050614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614a21565b8860ff16600203614c0d578715614b98576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015614b6d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190614b929190615a53565b50614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614b4f565b8860ff16600303614dae578715614c8b576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614b4f565b8015614d05576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614b4f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015614d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b929190615a53565b8860ff16600403614e5e578715614df1576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614a21565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6060614eaa8484600085614f73565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614edc9190615bd3565b6000604051808303816000865af19150503d8060008114614f19576040519150601f19603f3d011682016040523d82523d6000602084013e614f1e565b606091505b5091509150818015614f48575080511580614f48575080806020019051810190614f4891906159c3565b8015614f6a575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b606082471015615005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016111ac565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161502e9190615bd3565b60006040518083038185875af1925050503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b50915091506150818783838761508c565b979650505050505050565b6060831561512257825160000361511b5773ffffffffffffffffffffffffffffffffffffffff85163b61511b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016111ac565b5081614eaa565b614eaa83838151156151375781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac9190615bef565b6000610140828403121561517e57600080fd5b50919050565b6000806040838503121561519757600080fd5b823567ffffffffffffffff808211156151af57600080fd5b6151bb8683870161516b565b935060208501359150808211156151d157600080fd5b508301604081860312156151e457600080fd5b809150509250929050565b61ffff811681146151ff57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561525557615255615202565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156152a2576152a2615202565b604052919050565b600067ffffffffffffffff8211156152c4576152c4615202565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261530157600080fd5b813561531461530f826152aa565b61525b565b81815284602083860101111561532957600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146151ff57600080fd5b60008060008060008060c0878903121561538157600080fd5b863561538c816151ef565b9550602087013567ffffffffffffffff808211156153a957600080fd5b6153b58a838b016152f0565b965060408901359550606089013591506153ce82615346565b9093506080880135925060a088013590808211156153eb57600080fd5b506153f889828a016152f0565b9150509295509295509295565b60006020828403121561541757600080fd5b813567ffffffffffffffff81111561542e57600080fd5b614eaa8482850161516b565b60006020828403121561544c57600080fd5b813561116781615346565b60006020828403121561546957600080fd5b8135611167816151ef565b65ffffffffffff811681146151ff57600080fd5b60006020828403121561549a57600080fd5b813561116781615474565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154da57600080fd5b83018035915067ffffffffffffffff8211156154f557600080fd5b60200191503681900382131561550a57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b80516155de81615346565b919050565b80516155de816151ef565b80516155de81615474565b60005b838110156156145781810151838201526020016155fc565b50506000910152565b600082601f83011261562e57600080fd5b815161563c61530f826152aa565b81815284602083860101111561565157600080fd5b614eaa8260208301602087016155f9565b60006020828403121561567457600080fd5b815167ffffffffffffffff8082111561568c57600080fd5b9083019061014082860312156156a157600080fd5b6156a9615231565b6156b2836155d3565b81526156c0602084016155e3565b60208201526156d1604084016155e3565b60408201526156e2606084016155d3565b60608201526156f3608084016155d3565b608082015261570460a084016155d3565b60a082015260c083015160c082015260e083015160e082015261010061572b8185016155ee565b90820152610120838101518381111561574357600080fd5b61574f8882870161561d565b918301919091525095945050505050565b600081518084526157788160208601602086016155f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526157d160208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516157e8604084018261ffff169052565b50604083015161ffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c083015160e083015260e08301516101008181850152808501519150506101206158938185018365ffffffffffff169052565b840151610140848101529050614eaa610160840182615760565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561113a5761113a6158ad565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615920576159206158ad565b5060010190565b61ffff8281168282160390808211156143fb576143fb6158ad565b808202811582820484141761113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156159d557600080fd5b8151801515811461116757600080fd5b80516dffffffffffffffffffffffffffff811681146155de57600080fd5b600080600060608486031215615a1857600080fd5b615a21846159e5565b9250615a2f602085016159e5565b9150604084015163ffffffff81168114615a4857600080fd5b809150509250925092565b600060208284031215615a6557600080fd5b5051919050565b8082018082111561113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215615ac157600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b0357615b036158ad565b5060000390565b600060208284031215615b1c57600080fd5b815161116781615346565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615b9a610180840182615760565b905082810360e0840152615bae8186615760565b9050828103610100840152615bc38185615760565b9c9b505050505050505050505050565b60008251615be58184602087016155f9565b9190910192915050565b602081526000611167602083018461576056fea26469706673582212202ce6a8f21a153c83c150806f9ce2e260656621d27c2de20b34fdaa1dbce5be3f64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c8063a703fc4014610039578063ab8236f31461004e578063dcc455511461006e575b600080fd5b61004c610047366004615184565b610081565b005b34801561005a57600080fd5b5061004c610069366004615368565b6106c6565b61004c61007c366004615405565b6109ac565b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152906100fd9084018461543a565b73ffffffffffffffffffffffffffffffffffffffff1681526101256040840160208501615457565b61ffff16602082015261013e6060840160408501615457565b61ffff1660c0820152610157608084016060850161543a565b73ffffffffffffffffffffffffffffffffffffffff16604082015261018260a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0840135608083015260e084013560a08301526101c490840160408501615457565b61ffff1660c08201526101df61012084016101008501615488565b65ffffffffffff1660e082015260c083013561010082015261020760a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff9081166101408301526001610160830152336101208301819052346101a08401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e08101909152921691632b67b570919080606081018061028a60a08b0160808c0161543a565b73ffffffffffffffffffffffffffffffffffffffff908116825260c08b01351660208201526040016102c46101208b016101008c01615488565b65ffffffffffff908116825289351660209182015290825230908201526040016102f661012089016101008a01615488565b65ffffffffffff16905261030d60208701876154a5565b6040518563ffffffff1660e01b815260040161032c9493929190615511565b600060405180830381600087803b15801561034657600080fd5b505af115801561035a573d6000803e3d6000fd5b5050505060006103ae8480610120019061037491906154a5565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f4192505050565b90506103ba8183610f5b565b610100810151610140820151919350906103da60c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461043e576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61045b60e08701356104566060890160408a01615457565b611140565b821015610494576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8361018001516001036104a957505050505050565b6104e86104b9602088018861543a565b6104c960c0890160a08a0161543a565b6104d960408a0160208b01615457565b61ffff168960e001358661116e565b915081600003610524576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661059a5761054f608087016060880161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610594573d6000803e3d6000fd5b506105cb565b6105cb6105ad608088016060890161543a565b73ffffffffffffffffffffffffffffffffffffffff83169084611227565b6101a084015115610609576101a0840151604051339180156108fc02916000818181858888f19350505050158015610607573d6000803e3d6000fd5b505b61061960c0870160a0880161543a565b73ffffffffffffffffffffffffffffffffffffffff1661063f60a088016080890161543a565b73ffffffffffffffffffffffffffffffffffffffff16610662602089018961543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38960c00135866040516106b6929190918252602082015260400190565b60405180910390a4505050505050565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517fcebf3f7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601485015173ffffffffffffffffffffffffffffffffffffffff8116301461078d576040517fa9d0d13300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828060200190518101906107a39190615662565b608081015190915073ffffffffffffffffffffffffffffffffffffffff166107ca57600094505b3063dcc4555173ffffffffffffffffffffffffffffffffffffffff8716156107f35760006107f5565b855b604051806101400160405280856000015173ffffffffffffffffffffffffffffffffffffffff168152602001856020015161ffff168152602001856040015161ffff168152602001856060015173ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018560a0015173ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018560e00151815260200185610100015165ffffffffffff1681526020018561012001518152506040518363ffffffff1660e01b81526004016108e191906157aa565b6000604051808303818588803b1580156108fa57600080fd5b505af19350505050801561090c575060015b6109a25773ffffffffffffffffffffffffffffffffffffffff851661097b57806060015173ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610975573d6000803e3d6000fd5b506109a2565b60608101516109a29073ffffffffffffffffffffffffffffffffffffffff87169086611227565b5050505050505050565b6109be61012082016101008301615488565b65ffffffffffff164211156109ff576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101c08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082015290610a7b9083018361543a565b73ffffffffffffffffffffffffffffffffffffffff168152610aa36040830160208401615457565b61ffff166020820152610abc6060830160408401615457565b61ffff1660c0820152610ad5608083016060840161543a565b73ffffffffffffffffffffffffffffffffffffffff166040820152610b0060a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff1660608083019190915260c0830135608083015260e083013560a0830152610b4290830160408401615457565b61ffff1660c0820152610b5d61012083016101008401615488565b65ffffffffffff1660e082015260c0820135610100820152610b8560a083016080840161543a565b73ffffffffffffffffffffffffffffffffffffffff166101408201526000610bb360a084016080850161543a565b73ffffffffffffffffffffffffffffffffffffffff1603610c2c578160c00135341015610c0c576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c1a60c0830135346158dc565b6101a082015230610120820152610c3b565b33610120820152346101a08201525b6000610c4e6103746101208501856154a5565b9050610c5a8183610f5b565b61010081015161014082015191935090610c7a60c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cde576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cf660e08601356104566060880160408901615457565b821015610d2f576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836101800151600103610d43575050505050565b610d82610d53602087018761543a565b610d6360c0880160a0890161543a565b610d736040890160208a01615457565b61ffff168860e001358661116e565b915081600003610dbe576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e3457610de9608086016060870161543a565b73ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610e2e573d6000803e3d6000fd5b50610e47565b610e476105ad608087016060880161543a565b6101a084015115610e85576101a0840151604051339180156108fc02916000818181858888f19350505050158015610e83573d6000803e3d6000fd5b505b610e9560c0860160a0870161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ebb60a087016080880161543a565b73ffffffffffffffffffffffffffffffffffffffff16610ede602088018861543a565b73ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38860c0013586604051610f32929190918252602082015260400190565b60405180910390a45050505050565b604080518082019091528181528151909101602082015290565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000610fde8480516001018051915290565b60ff16905060005b818110156111345760006110008680516001018051915290565b60ff1690506001810361101d5761101685611300565b9450611121565b6002810361102e57611016856114d0565b600381036110405761101686866117f2565b60048103611052576110168686611e2a565b600581036110645761101686866121c1565b600681036110765761101686866129e3565b60078103611088576110168686612f20565b6008810361109a576110168686613471565b600981036110ef576110ad6001846158dc565b82146110e5576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61101686866138fd565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061112c816158ef565b915050610fe6565b50829150505b92915050565b600061271061114f8382615927565b61115d9061ffff1685615942565b6111679190615988565b9392505050565b60006107d08411156111b5576040517f7b9314200000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156111c7575050828203835b612710818702049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156111fd5760646032840204611200565b60005b9050808303838214611218576112188a8a8484614125565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112fb9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526141ed565b505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140808201839052610160820183905261018082018390526101a0820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff16156113e5576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff163014611439576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166101408401819052610100840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b1580156114b057600080fd5b505af11580156114c4573d6000803e3d6000fd5b50959695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805461014085015191925073ffffffffffffffffffffffffffffffffffffffff9182169116146115be576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61012083015173ffffffffffffffffffffffffffffffffffffffff811630148015906115ec57306101208601525b6000610140860152801561175a578461016001516001036116b057600183015461010086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b5050505061175a565b82546101008601516040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015230602483015260448201929092529116906323b872dd906064016020604051808303816000875af1158015611734573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175891906159c3565b505b82546101008601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d916117b79160040190815260200190565b600060405180830381600087803b1580156117d157600080fd5b505af11580156117e5573d6000803e3d6000fd5b5096979650505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261014082015173ffffffffffffffffffffffffffffffffffffffff166118b5576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff1660608201526101208301513073ffffffffffffffffffffffffffffffffffffffff909116036119aa576119a5816020015184610100015185610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b611ad8565b826101600151600103611a90577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015461012084015160208301516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015611a7357600080fd5b505af1158015611a87573d6000803e3d6000fd5b50505050611ad0565b611ad0836101200151826020015185610100015186610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208401525b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151611b7e57905b606083015161010086015161ffff6127109283031691840290820290810190830281611bac57611bac615959565b046101008701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611c22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c469190615a53565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8560400151611c7c57876101000151611c7f565b60005b8660400151611c8f576000611c96565b8861010001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b158015611d0057600080fd5b505af1158015611d14573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190615a53565b905081811080611dca5750610100870151611dc79083615a6c565b81105b15611e01576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1661014085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526000611ead8480516001018051915290565b60ff1690506000836101000151905060006002831015611ef9576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b8581101561218c576000611f146001886158dc565b8210611f205785611f51565b612710611f338b80516002018051915290565b61ffff168a6101000151611f479190615942565b611f519190615988565b905085811115611f8d576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f9781876158dc565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610120808201838152610140808401858152610160850186905261018085018690526101a08501959095526101008401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d01511690915290965061203e8b82610f5b565b905080610180015160010361207f576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361209c5780610120015193508061014001519450612170565b8473ffffffffffffffffffffffffffffffffffffffff1681610140015173ffffffffffffffffffffffffffffffffffffffff1614612106576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1681610120015173ffffffffffffffffffffffffffffffffffffffff1614612170576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008101516121809087615a6c565b95505050600101611eff565b5073ffffffffffffffffffffffffffffffffffffffff9081166101208801521661014086015261010085015250919392505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915261225660405180606001604052806060815260200160608152602001606081525090565b60006122688580516001018051915290565b60ff169050612278816001615a6c565b67ffffffffffffffff81111561229057612290615202565b6040519080825280602002602001820160405280156122b9578160200160208202803683370190505b5080835261014085015181519091906000906122d7576122d7615a7f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561237057855160140180519087528351612333836001615a6c565b8151811061234357612343615a7f565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612314565b5061237b8582614360565b602083015261238a8582614402565b60408301528151805160009190839081106123a7576123a7615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561241d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124419190615a53565b9050600061246284604001518761010001518660000151876020015161448b565b90503073ffffffffffffffffffffffffffffffffffffffff1686610120015173ffffffffffffffffffffffffffffffffffffffff16036124f4576124ef84602001516000815181106124b6576124b6615a7f565b602002602001015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166112279092919063ffffffff16565b61265f565b8561016001516001036125fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546101208701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061256057612560615a7f565b60200260200101518961010001518a61014001516040518563ffffffff1660e01b81526004016125c6949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b50505050612657565b612657866101200151856020015160008151811061261d5761261d615a7f565b602002602001015188610100015189610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208701525b60005b83811015612863576000612677826001615a6c565b905060008660000151828151811061269157612691615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16876000015184815181106126c5576126c5615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16106126ef5760006126f2565b60015b90506000600288600001515161270891906158dc565b84106127145730612733565b8760200151838151811061272a5761272a615a7f565b60200260200101515b90508760200151848151811061274b5761274b615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836127925786858151811061278557612785615a7f565b6020026020010151612795565b60005b846127a15760006127bc565b8786815181106127b3576127b3615a7f565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561283c57600080fd5b505af1158015612850573d6000803e3d6000fd5b5050600190950194506126629350505050565b5060008460000151848151811061287c5761287c615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156128f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129169190615a53565b9050816001835161292791906158dc565b8151811061293757612937615a7f565b6020026020010151876101000181815250508281108061296557506101008701516129629084615a6c565b81105b1561299c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518051859081106129b0576129b0615a7f565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1661014088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015261014084015116612afe576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b909190615a53565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff1685610140015173ffffffffffffffffffffffffffffffffffffffff16109050612c376040518060800160405280876101000151815260200187610120015173ffffffffffffffffffffffffffffffffffffffff16815260200187610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018761016001518152506146c0565b8015612d1b5760208301516101008601516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d029190615aae565b91505080612d0f90615ad2565b61010087015250612e03565b60208301516101008601516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612def9190615aae565b509050612dfb81615ad2565b610100870152505b612e0b61484f565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9d9190615a53565b905082811080612ebb5750610100860151612eb89084615a6c565b81105b15612ef2576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff16610140840152505030610120820152919050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a0810191909152612fb560405180606001604052806060815260200160608152602001606081525090565b6000612fc78580516001018051915290565b60ff169050612fd68582614360565b8252612fe28582614360565b60208301528151600090612ff76001846158dc565b8151811061300757613007615a7f565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190615a53565b905060005b8381101561337957600081156130e55785516130c86001846158dc565b815181106130d8576130d8615a7f565b60200260200101516130ec565b8761014001515b90508560000151828151811061310457613104615a7f565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166101408b01819052604080516080810182526101008d015181526101208d01518416948101949094529184169183018290526101608b015160608401521190613170906146c0565b8260000361318057306101208a01525b60008760200151848151811061319857613198615a7f565b602002602001015190508115613282576101008a01516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015613245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132699190615aae565b9150508061327690615ad2565b6101008c015250613366565b6101008a01516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561332e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133529190615aae565b50905061335e81615ad2565b6101008c0152505b61336e61484f565b5050506001016130ab565b506101408601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156133ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134109190615a53565b90508181108061342e575061010087015161342b9083615a6c565b81105b15613465576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a0820152610140830151815161012085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146136fe578461016001516001036136ba577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208601516101008701516101408801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561369d57600080fd5b505af11580156136b1573d6000803e3d6000fd5b505050506136f6565b6136f68561012001513087610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208601525b60008161379b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613772573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137969190615a53565b61379d565b475b9050826137dd576137dd846020015187610100015188610140015173ffffffffffffffffffffffffffffffffffffffff166148af9092919063ffffffff16565b61382284608001518560a001518660200151866137fb576000613802565b8961010001515b886040015189606001518c610100015160008b8061381d57508a5b61499f565b6000826138bf5784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015613896573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ba9190615a53565b6138c1565b475b855173ffffffffffffffffffffffffffffffffffffffff1661014089015290506138eb82826158dc565b61010088015250949695505050505050565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101919091526139a46040518060a00160405280600061ffff168152602001600081526020016000815260200160008152602001606081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff1660408201528351600401805190855263ffffffff166060820181905215613b31576040805161014080820183526000808352602080840182815284860183815260608087018581526080880186815260a0890187905260c0808a0188905260e08a018890526101008a01979097526101208901929092528b5173ffffffffffffffffffffffffffffffffffffffff9081168952948c015161ffff908116909452948b0151909216905294880151811690915290860151169091528451601401805190865273ffffffffffffffffffffffffffffffffffffffff1660a08201528451602001805190865260e08281019190915284015165ffffffffffff16610100820152845160208082018051909201018652610120820152604051613afc9082906020016157aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526080830152505b826060015173ffffffffffffffffffffffffffffffffffffffff1683610140015173ffffffffffffffffffffffffffffffffffffffff1614613c4357806080015151600003613ba55782516101408401516020850151610100860151613b9e93929161ffff16908061116e565b6101008401525b82610140015173ffffffffffffffffffffffffffffffffffffffff16836060015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f1d81b4318b379c644b5546ae9cf37d861a5c7547bf3dae6cfaecffa12f8748f38660800151876101000151604051613c3a929190918252602082015260400190565b60405180910390a45b613c558360a001518460c00151611140565b8361010001511015613c93576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015173ffffffffffffffffffffffffffffffffffffffff918216911615613ecd5761012084015173ffffffffffffffffffffffffffffffffffffffff163014613e1f57836101600151600103613ddb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546101208501516101008601516101408701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015613dbe57600080fd5b505af1158015613dd2573d6000803e3d6000fd5b50505050613e17565b613e178461012001513086610100015187610140015173ffffffffffffffffffffffffffffffffffffffff166142fc909392919063ffffffff16565b306101208501525b613ecd826080015151600014613e355781613ea4565b8173ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea49190615b0a565b61010086015161014087015173ffffffffffffffffffffffffffffffffffffffff1691906148af565b600161018085015260808201515115613ee65780613f55565b8073ffffffffffffffffffffffffffffffffffffffff1663a9e56f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f559190615b0a565b73ffffffffffffffffffffffffffffffffffffffff16639fbf10fc600073ffffffffffffffffffffffffffffffffffffffff1686610140015173ffffffffffffffffffffffffffffffffffffffff1614613fb457856101a00151613fca565b856101a00151866101000151613fca9190615a6c565b8451602086015160408701516101008a015160c08b0151309190613fef908290611140565b60405180606001604052808c606001518152602001600081526020016040518060200160405280600081525081525060008c608001515111614035578d60400151614037565b305b604051602001614072919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905260808e01517fffffffff0000000000000000000000000000000000000000000000000000000060e08d901b1683526140e29998979695949392600401615b27565b6000604051808303818588803b1580156140fb57600080fd5b505af115801561410f573d6000803e3d6000fd5b505060006101a088015250949695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84811660008181527f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc90602081815260408084209589168085529582528084208054890190557f77fbd1c38a5ead50a5764a860fef6b91e5432a95f91228e67197edaf911cfc9182529283902080548801905582518781529081018690528251919493927f3d2a5b5aa3c9e4a41eed8ae2e9e470c5cfb96fa51eb0935c607c0fd8ec3f3f5792918290030190a35050505050565b600061424f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614e9b9092919063ffffffff16565b905080516000148061427057508080602001905181019061427091906159c3565b6112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016111ac565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261435a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611279565b50505050565b60608167ffffffffffffffff81111561437b5761437b615202565b6040519080825280602002602001820160405280156143a4578160200160208202803683370190505b50905060005b828110156143fb57835160140180519085528282815181106143ce576143ce615a7f565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016143aa565b5092915050565b60608167ffffffffffffffff81111561441d5761441d615202565b604051908082528060200260200182016040528015614446578160200160208202803683370190505b50905060005b828110156143fb578351600201805190855282828151811061447057614470615a7f565b61ffff9092166020928302919091019091015260010161444c565b805182516060919067ffffffffffffffff8111156144ab576144ab615202565b6040519080825280602002602001820160405280156144d4578160200160208202803683370190505b50915084826000815181106144eb576144eb615a7f565b60200260200101818152505060005b818110156146b657600085828151811061451657614516615a7f565b602002602001015190506000868360016145309190615a6c565b8151811061454057614540615a7f565b60200260200101519050600089848151811061455e5761455e615a7f565b60200260200101516127106145739190615927565b61ffff16905060008088868151811061458e5761458e615a7f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156145e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146049190615a03565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561465f57905b828b0282612710020181848d02028161467a5761467a615959565b049a508a8861468a886001615a6c565b8151811061469a5761469a615a7f565b60209081029190910101525050600190930192506144fa915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361471e576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff9384161790915560408301517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549092169216919091179055606001517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7e55565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036148ad576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261493b8482614eb2565b61435a5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526149959085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611279565b61435a84826141ed565b8860ff16600103614acd578715614a58576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b6000604051808303818588803b158015614a3a57600080fd5b505af1158015614a4e573d6000803e3d6000fd5b5050505050614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614a21565b8860ff16600203614c0d578715614b98576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff88169063a6417ed69088906084015b60206040518083038185885af1158015614b6d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190614b929190615a53565b50614e90565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808716600f90810b6004840152908616900b6024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690633df02124908890608401614b4f565b8860ff16600303614dae578715614c8b576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff8816906365b2489b908890608401614b4f565b8015614d05576040517f394747c500000000000000000000000000000000000000000000000000000000815260ff80871660048301528516602482015260448101849052606481018390526001608482015273ffffffffffffffffffffffffffffffffffffffff88169063394747c590889060a401614b4f565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff868116600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908906084016020604051808303816000875af1158015614d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b929190615a53565b8860ff16600403614e5e578715614df1576040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808716600483015285166024820152604481018490526064810183905273ffffffffffffffffffffffffffffffffffffffff881690635b41b908908890608401614a21565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b6060614eaa8484600085614f73565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051614edc9190615bd3565b6000604051808303816000865af19150503d8060008114614f19576040519150601f19603f3d011682016040523d82523d6000602084013e614f1e565b606091505b5091509150818015614f48575080511580614f48575080806020019051810190614f4891906159c3565b8015614f6a575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b606082471015615005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016111ac565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161502e9190615bd3565b60006040518083038185875af1925050503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b50915091506150818783838761508c565b979650505050505050565b6060831561512257825160000361511b5773ffffffffffffffffffffffffffffffffffffffff85163b61511b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016111ac565b5081614eaa565b614eaa83838151156151375781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ac9190615bef565b6000610140828403121561517e57600080fd5b50919050565b6000806040838503121561519757600080fd5b823567ffffffffffffffff808211156151af57600080fd5b6151bb8683870161516b565b935060208501359150808211156151d157600080fd5b508301604081860312156151e457600080fd5b809150509250929050565b61ffff811681146151ff57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561525557615255615202565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156152a2576152a2615202565b604052919050565b600067ffffffffffffffff8211156152c4576152c4615202565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261530157600080fd5b813561531461530f826152aa565b61525b565b81815284602083860101111561532957600080fd5b816020850160208301376000918101602001919091529392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146151ff57600080fd5b60008060008060008060c0878903121561538157600080fd5b863561538c816151ef565b9550602087013567ffffffffffffffff808211156153a957600080fd5b6153b58a838b016152f0565b965060408901359550606089013591506153ce82615346565b9093506080880135925060a088013590808211156153eb57600080fd5b506153f889828a016152f0565b9150509295509295509295565b60006020828403121561541757600080fd5b813567ffffffffffffffff81111561542e57600080fd5b614eaa8482850161516b565b60006020828403121561544c57600080fd5b813561116781615346565b60006020828403121561546957600080fd5b8135611167816151ef565b65ffffffffffff811681146151ff57600080fd5b60006020828403121561549a57600080fd5b813561116781615474565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126154da57600080fd5b83018035915067ffffffffffffffff8211156154f557600080fd5b60200191503681900382131561550a57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b80516155de81615346565b919050565b80516155de816151ef565b80516155de81615474565b60005b838110156156145781810151838201526020016155fc565b50506000910152565b600082601f83011261562e57600080fd5b815161563c61530f826152aa565b81815284602083860101111561565157600080fd5b614eaa8260208301602087016155f9565b60006020828403121561567457600080fd5b815167ffffffffffffffff8082111561568c57600080fd5b9083019061014082860312156156a157600080fd5b6156a9615231565b6156b2836155d3565b81526156c0602084016155e3565b60208201526156d1604084016155e3565b60408201526156e2606084016155d3565b60608201526156f3608084016155d3565b608082015261570460a084016155d3565b60a082015260c083015160c082015260e083015160e082015261010061572b8185016155ee565b90820152610120838101518381111561574357600080fd5b61574f8882870161561d565b918301919091525095945050505050565b600081518084526157788160208601602086016155f9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526157d160208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516157e8604084018261ffff169052565b50604083015161ffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c083015160e083015260e08301516101008181850152808501519150506101206158938185018365ffffffffffff169052565b840151610140848101529050614eaa610160840182615760565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561113a5761113a6158ad565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615920576159206158ad565b5060010190565b61ffff8281168282160390808211156143fb576143fb6158ad565b808202811582820484141761113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826159be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156159d557600080fd5b8151801515811461116757600080fd5b80516dffffffffffffffffffffffffffff811681146155de57600080fd5b600080600060608486031215615a1857600080fd5b615a21846159e5565b9250615a2f602085016159e5565b9150604084015163ffffffff81168114615a4857600080fd5b809150509250925092565b600060208284031215615a6557600080fd5b5051919050565b8082018082111561113a5761113a6158ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215615ac157600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203615b0357615b036158ad565b5060000390565b600060208284031215615b1c57600080fd5b815161116781615346565b600061012061ffff8c1683528a602084015289604084015273ffffffffffffffffffffffffffffffffffffffff891660608401528760808401528660a08401528060c084015285518184015250602085015161014083015260408501516060610160840152615b9a610180840182615760565b905082810360e0840152615bae8186615760565b9050828103610100840152615bc38185615760565b9c9b505050505050505050505050565b60008251615be58184602087016155f9565b9190910192915050565b602081526000611167602083018461576056fea26469706673582212202ce6a8f21a153c83c150806f9ce2e260656621d27c2de20b34fdaa1dbce5be3f64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json b/packages/hardhat/deployments/optimism/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json new file mode 100644 index 00000000..cf1aa121 --- /dev/null +++ b/packages/hardhat/deployments/optimism/solcInputs/c6735d71c8937120ee5b82bc32fb5df3.json @@ -0,0 +1,170 @@ +{ + "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" + }, + "@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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * Perform the swap with tokens already moved to this contract\n */\n function curveExactInputSingleInternal(\n ExactInputSingleParams calldata params\n ) internal returns (uint256 amountOut) {\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 LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n useEth: params.tokenIn == address(0) || isToEth,\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 = LibStarVault.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 emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function curveExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (params.tokenIn == address(0)) {\n revert PermitForEthToken();\n }\n\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 return curveExactInputSingleInternal(params);\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\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 IERC20(params.tokenIn).safeTransferFrom(msg.sender, address(this), params.amountIn);\n }\n\n return curveExactInputSingleInternal(params);\n }\n}\n" + }, + "contracts/facets/Stargate.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 {IStargate} from '../interfaces/IStargate.sol';\nimport {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract Stargate is IStargate {\n using SafeERC20 for IERC20;\n\n /**\n * Jump tokens with Stargate with input tokens already moved to this contract\n */\n function stargateJumpTokenInternal(JumpTokenParams calldata params) internal {\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.token,\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n // NOTE: This lookup is spending 319 gas\n IStargateRouter stargateRouter = IStargateRouter(\n LibWarp.state().stargateComposer.stargateRouter()\n );\n\n IERC20(params.token).forceApprove(address(stargateRouter), amountIn);\n\n unchecked {\n stargateRouter.swap{value: msg.value}({\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\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > (params.amountIn - amountIn)\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\n }\n }\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable {\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.token,\n amount: 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 // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n uint160(params.amountIn),\n params.token\n );\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable {\n // Transfer tokens from the sender to this contract\n IERC20(params.token).safeTransferFrom(msg.sender, address(this), params.amountIn);\n\n stargateJumpTokenInternal(params);\n }\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n // NOTE: It is not possible to know how many tokens will be delivered. Therfore positive slippage\n // is never charged\n uint256 amountIn = LibStarVault.calculateAndRegisterFee(\n params.partner,\n address(0),\n params.feeBps,\n params.amountIn,\n params.amountIn\n );\n\n unchecked {\n LibWarp.state().stargateComposer.swap{value: msg.value - (params.amountIn - amountIn)}({\n _dstChainId: params.dstChainId,\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n _refundAddress: payable(msg.sender),\n _amountLD: amountIn,\n // Apply slippage to the amountOutExpected after fees\n _minAmountLD: params.amountOutExpected > params.amountIn - amountIn\n ? LibWarp.applySlippage(\n params.amountOutExpected - (params.amountIn - amountIn),\n params.slippageBps\n )\n : 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(params.recipient),\n _payload: ''\n });\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 {LibStarVault} from '../libraries/LibStarVault.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 /**\n * NOTE: The tokens must already have been moved to the first pool\n */\n function uniswapV2LikeExactInputSingleInternal(\n ExactInputSingleParams memory params\n ) internal returns (uint256 amountOut) {\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 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 = 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 = LibStarVault.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 emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : params.tokenIn,\n isToEth ? address(0) : params.tokenOut,\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pool, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, params.pool, params.amountIn);\n }\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 the pool\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pool,\n (uint160)(params.amountIn),\n params.tokenIn\n );\n\n return uniswapV2LikeExactInputSingleInternal(params);\n }\n\n function uniswapV2LikeExactInputInternal(\n ExactInputParams calldata params\n ) internal returns (uint256 amountOut) {\n LibWarp.State storage s = LibWarp.state();\n\n address[] memory tokens = params.tokens;\n uint256 poolLength = params.pools.length;\n bool isFromEth = tokens[0] == address(0);\n bool isToEth = tokens[poolLength] == address(0);\n\n if (isFromEth) {\n tokens[0] = address(s.weth);\n }\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n 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 // 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 = tokens[index] < tokens[indexPlusOne] ? true : false;\n address to = index < 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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n 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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n // NOTE: The tokens may have been rewritten to WETH\n isFromEth ? address(0) : tokens[0],\n isToEth ? address(0) : tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(address(LibWarp.state().weth)).safeTransfer(params.pools[0], params.amountIn);\n } else {\n IERC20(params.tokens[0]).safeTransferFrom(msg.sender, params.pools[0], params.amountIn);\n }\n\n return uniswapV2LikeExactInputInternal(params);\n }\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n // Permit tokens / set allowance\n LibWarp.state().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 LibWarp.state().permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n\n return uniswapV2LikeExactInputInternal(params);\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 {LibStarVault} from '../libraries/LibStarVault.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\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /**\n * NOTE: The tokens must already have been transferred to the pool\n */\n function uniswapV2ExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n address pair\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address tokenIn = params.tokenIn == address(0) ? address(s.weth) : params.tokenIn;\n address tokenOut = params.tokenOut == address(0) ? address(s.weth) : params.tokenOut;\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (tokenIn > 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 InsufficientOutputAmount();\n }\n\n bool zeroForOne = tokenIn < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.tokenOut == address(0)) {\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn == address(0) ? address(s.weth) : params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\n if (params.tokenIn == address(0)) {\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(address(s.weth)).safeTransfer(pair, params.amountIn);\n } else {\n IERC20(params.tokenIn).safeTransferFrom(msg.sender, pair, params.amountIn);\n }\n\n return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n address pair = LibUniV2Router.pairFor(\n s.uniswapV2Factory,\n params.tokenIn,\n params.tokenOut == address(0) ? address(s.weth) : params.tokenOut\n );\n\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 return uniswapV2ExactInputSingleInternal(params, pair);\n }\n\n /**\n * NOTE: The tokens must already have been transferred to the first pool\n *\n * The path should be rewritten so address(0) is replaced by the WETH address\n */\n function uniswapV2ExactInputInternal(\n ExactInputParams calldata params,\n address[] memory path,\n address[] memory pairs,\n uint256[] memory amounts\n ) internal returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\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 = path[index] < path[indexPlusOne] ? true : false;\n address to = index < 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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert ZeroAmountOut();\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH. 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(path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.path[0],\n params.path[pathLengthMinusOne],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[0] == address(0)) {\n // From ETH\n path[0] = address(s.weth);\n }\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert InsufficientOutputAmount();\n }\n\n if (params.path[0] == address(0)) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer WETH tokens to the first pool\n IERC20(path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n IERC20(path[0]).safeTransferFrom(msg.sender, pairs[0], params.amountIn);\n }\n\n return uniswapV2ExactInputInternal(params, path, pairs, amounts);\n }\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n address[] memory path = params.path;\n\n if (params.path[pathLengthMinusOne] == address(0)) {\n // To ETH\n path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n path\n );\n\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: 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 return uniswapV2ExactInputInternal(params, path, pairs, amounts);\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 if (callback.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n } else {\n IERC20(callback.token).safeTransferFrom(callback.payer, msg.sender, callback.amount);\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 /**\n * NOTE: None of these arguments can be trusted\n */\n function pancakeV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function ramsesV2SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * KyperSwap V2 callback\n * NOTE: None of these arguments can be trusted\n */\n function swapCallback(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 {LibStarVault} from '../libraries/LibStarVault.sol';\nimport {LibWarp} from '../libraries/LibWarp.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 uniswapV3LikeExactInputSingleInternal(\n ExactInputSingleParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n bool isFromEth = params.tokenIn == address(0);\n address tokenIn = isFromEth ? address(LibWarp.state().weth) : params.tokenIn;\n\n address tokenOut = params.tokenOut == address(0)\n ? address(LibWarp.state().weth)\n : params.tokenOut;\n\n uint256 tokenOutBalancePrev = IERC20(tokenOut).balanceOf(address(this));\n\n bool zeroForOne = tokenIn < tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: tokenIn,\n amount: params.amountIn,\n usePermit: usePermit\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokenOut == address(0)) {\n // To ETH, unwrap WETH\n // TODO: This is read twice. Compare gas usage\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(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn == address(0)) {\n // From ETH, wrap it\n IWETH weth = LibWarp.state().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 return uniswapV3LikeExactInputSingleInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputSingleInternal(params, 1);\n }\n\n function uniswapV3LikeExactInputInternal(\n ExactInputParams calldata params,\n uint256 usePermit\n ) internal returns (uint256 amountOut) {\n uint256 poolLength = params.pools.length;\n address payer = params.tokens[0] == address(0) ? address(this) : msg.sender;\n address[] memory tokens = params.tokens;\n\n if (params.tokens[0] == address(0)) {\n tokens[0] = address(LibWarp.state().weth);\n }\n\n if (params.tokens[poolLength] == address(0)) {\n tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = tokens[index] < tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: payer,\n token: tokens[index],\n amount: amountOut,\n usePermit: usePermit\n })\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(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 = LibStarVault.calculateAndRegisterFee(\n params.partner,\n tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (params.tokens[poolLength] == address(0)) {\n // To ETH, unwrap\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(tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n\n emit LibWarp.Warp(\n params.partner,\n params.tokens[0],\n params.tokens[poolLength],\n params.amountIn,\n amountOut\n );\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokens[0] == address(0)) {\n // From ETH, wrap it\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n LibWarp.state().weth.deposit{value: msg.value}();\n }\n\n return uniswapV3LikeExactInputInternal(params, 0);\n }\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut) {\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 return uniswapV3LikeExactInputInternal(params, 1);\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 {LibStarVault} from '../libraries/LibStarVault.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';\nimport {IStargateReceiver} from '../interfaces/external/IStargateReceiver.sol';\nimport {IStargateComposer} from '../interfaces/external/IStargateComposer.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, IStargateReceiver, 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 uint256 dstGasForCall;\n bytes payload;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n address paramTokenIn;\n uint256 paramAmountIn;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint48 paramDeadline;\n uint256 amount;\n address payer;\n address token;\n /**\n * Whether to use a permit transfer (0 or 1). Only applicable when `payer` is not `address(this)`\n */\n uint256 usePermit;\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 if (t.usePermit == 1) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(address(s.weth)).transferFrom(prevPayer, address(this), t.amount);\n }\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 if (t.usePermit == 1) {\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pool, t.amount);\n }\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(\n t.payer,\n params.pools[0],\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, params.pools[0], t.amount);\n }\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({\n payer: t.payer,\n token: t.token,\n amount: t.amount,\n usePermit: t.usePermit\n })\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({\n payer: t.payer,\n token: tokenIn,\n amount: t.amount,\n usePermit: t.usePermit\n })\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 if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\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 useEth: isFromEth || isToEth,\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 * Cross-chain callback from Stargate\n *\n * The tokens have already been received by this contract, `t.payer` is set to this contract\n * before `sgReceive` is called by the router.\n *\n * The `_nonce` field is not checked since it's assumed that LayerZero will not deliver the\n * same message more than once.\n *\n * The Stargate composer is trusted, meaning `_token` and `amountLD` is not verified. Should the\n * Stargate composer be compromised, an attacker can drain this contract.\n *\n * If the payload can not be decoded, tokens are left in this contract.\n * If execution runs out of gas, tokens are left in this contract.\n *\n * If an error occurs during engage, such as insufficient output amount, tokens are refunded\n * to the recipient.\n *\n * See https://stargateprotocol.gitbook.io/stargate/interfaces/evm-solidity-interfaces/istargatereceiver.sol\n */\n function sgReceive(\n uint16, // _srcChainId\n bytes memory _srcAddress,\n uint256, // _nonce\n address _token,\n uint256 amountLD,\n bytes memory payload\n ) external {\n if (msg.sender != address(LibWarp.state().stargateComposer)) {\n revert InvalidSgReceiverSender();\n }\n\n // NOTE: Addresses cannot be decode from bytes using `abi.decode`\n // From https://ethereum.stackexchange.com/a/50528\n address srcAddress;\n\n assembly {\n srcAddress := mload(add(_srcAddress, 20))\n }\n\n if (srcAddress != address(this)) {\n // NOTE: This assumes that this contract is deployed at the same address on every chain\n revert InvalidSgReceiveSrcAddress();\n }\n\n Params memory params = abi.decode(payload, (Params));\n\n if (params.tokenIn == address(0)) {\n // Distinguish between receiving ETH and SGETH. Note that the `params.tokenIn` address is useless\n // otherwise because `_token` may be different on this chain\n _token = address(0);\n }\n\n try\n IWarpLink(this).warpLinkEngage{value: _token == address(0) ? amountLD : 0}(\n Params({\n partner: params.partner,\n feeBps: params.feeBps,\n slippageBps: params.slippageBps,\n recipient: params.recipient,\n tokenIn: _token,\n tokenOut: params.tokenOut,\n amountIn: amountLD,\n amountOut: params.amountOut,\n deadline: params.deadline,\n commands: params.commands\n })\n )\n {} catch {\n // Refund tokens to the recipient\n if (_token == address(0)) {\n payable(params.recipient).transfer(amountLD);\n } else {\n IERC20(_token).safeTransfer(params.recipient, amountLD);\n }\n }\n }\n\n /**\n * Jump to another chain using the Stargate bridge\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 * If the jump is the final operation, meaning the tokens will be delivered to the recipient on\n * the other chain without further processing, the fee is charged and the `Warp` event is emitted\n * in this function.\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 * - dstGasForCall (uint32)\n * - tokenOut (address) when `dstGasForCall` > 0\n * - amountOut (uint256) when `dstGasForCall` > 0\n * - commands (uint256 length, ...bytes) when `dstGasForCall` > 0\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n // TODO: Does this use the same gas than (a, b, c,) = (stream.read, ...)?\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n params.dstGasForCall = stream.readUint32();\n\n if (params.dstGasForCall > 0) {\n // NOTE: `amountIn` is left as zero\n Params memory destParams;\n destParams.partner = t.paramPartner;\n destParams.feeBps = t.paramFeeBps;\n destParams.slippageBps = t.paramSlippageBps;\n destParams.recipient = t.paramRecipient;\n // NOTE: Used to distinguish ETH vs SGETH. Tokens on the other chain do not not necessarily have\n // the same address as on this chain\n destParams.tokenIn = t.token;\n destParams.tokenOut = stream.readAddress();\n destParams.amountOut = stream.readUint256();\n destParams.deadline = t.paramDeadline;\n destParams.commands = stream.readBytes();\n params.payload = abi.encode(destParams);\n }\n\n if (t.token != t.paramTokenIn) {\n if (params.payload.length == 0) {\n // If the tokens are being delivered directly to the recipient without a second\n // WarpLink engage, the fee is charged on this chain\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\n // is never charged\n t.amount = LibStarVault.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n }\n\n emit LibWarp.Warp(t.paramPartner, t.paramTokenIn, t.token, t.paramAmountIn, 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 IStargateComposer stargateComposer = LibWarp.state().stargateComposer;\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n if (t.usePermit == 1) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(\n t.payer,\n address(this),\n (uint160)(t.amount),\n t.token\n );\n } else {\n // NOTE: `t.usePermit` is left as 1\n IERC20(t.token).safeTransferFrom(t.payer, address(this), t.amount);\n }\n\n // Update the payer to this contract\n // TODO: Is this value ever read?\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens. When there is a payload, the composer is used, else the router\n IERC20(t.token).forceApprove(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer),\n t.amount\n );\n }\n\n t.jumped = 1;\n\n // Swap on the composer if there is a payload, else the router\n IStargateRouter(\n params.payload.length == 0 ? stargateComposer.stargateRouter() : address(stargateComposer)\n ).swap{\n value: t.token == address(0) ? t.amount + t.nativeValueRemaining : t.nativeValueRemaining\n }({\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 // TODO: Use `msg.sender` if it's EOA, else use this contract\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // NOTE: This is imperfect because the user may already have eaten some slippage and may eat\n // more on the other chain. It also assumes the tokens are of nearly equal value\n _minAmountLD: LibWarp.applySlippage(t.amount, t.paramSlippageBps),\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: params.dstGasForCall,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n // NOTE: This assumes the contract is deployed at the same address on every chain.\n // If this is not the case, a new param needs to be added with the next WarpLink address\n _to: abi.encodePacked(params.payload.length > 0 ? address(this) : t.paramRecipient),\n _payload: params.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 calldata params) 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.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\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\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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\n }\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable {\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramSlippageBps = params.slippageBps;\n t.paramRecipient = params.recipient;\n t.paramTokenIn = params.tokenIn;\n t.paramAmountIn = params.amountIn;\n t.paramAmountOut = params.amountOut;\n t.paramSlippageBps = params.slippageBps;\n t.paramDeadline = params.deadline;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.usePermit = 1;\n\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 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.jumped == 1) {\n // The coins have jumped away from this chain. Fees are colelcted before\n // the jump or on the other chain.\n //\n // `t.nativeValueRemaining` is not checked since it should be zero\n return;\n }\n\n // Collect fees\n amountOut = LibStarVault.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert InsufficientOutputAmount();\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 if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n emit LibWarp.Warp(params.partner, params.tokenIn, params.tokenOut, params.amountIn, amountOut);\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(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy,\n bool use_eth\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\n// Kind 4, uint256s with no return value\n// Example v0.2.15, \"Pool for USDT/BTC/ETH or similar\"\n// See https://arbiscan.io/address/0x960ea3e3C7FB317332d990873d354E18d7645590#code\ninterface ICurvePoolKind4 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external payable;\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/IStargateComposer.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\nimport {IStargateRouter} from './IStargateRouter.sol';\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateComposer is IStargateRouter {\n function stargateRouter() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/IStargateReceiver.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\n\ninterface IStargateReceiver {\n function sgReceive(\n uint16 _srcChainId, // the remote chainId sending the tokens\n bytes memory _srcAddress, // the remote Bridge address\n uint256 _nonce,\n address _token, // the token contract on the local chain\n uint256 amountLD, // the qty of local _token contract tokens\n bytes memory payload\n ) 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface ICurve is ILibCurve, ILibStarVault, ILibWarp {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n /**\n * A function expecting a permit was used when the input token is ETH\n */\n error PermitForEthToken();\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 curveExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/ILibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibCurve {\n error UnhandledPoolKind();\n}\n" + }, + "contracts/interfaces/ILibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n}\n" + }, + "contracts/interfaces/ILibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n}\n" + }, + "contracts/interfaces/ILibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface ILibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n}\n" + }, + "contracts/interfaces/IStargate.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\n\ninterface IStargate is ILibStarVault {\n error InsufficientEthValue();\n\n struct JumpTokenParams {\n address token;\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n struct JumpNativeParams {\n /**\n * The amount in is passed to distinguish the amount to bridge from the fee\n */\n uint160 amountIn;\n /**\n * The amount the user was quoted. Used to calculate the minimum acceptable\n * amount of tokens to receive.\n */\n uint160 amountOutExpected;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n uint16 dstChainId;\n uint8 srcPoolId;\n uint8 dstPoolId;\n }\n\n function stargateJumpToken(JumpTokenParams calldata params) external payable;\n\n function stargateJumpTokenPermit(\n JumpTokenParams calldata params,\n PermitParams calldata permit\n ) external payable;\n\n function stargateJumpNative(JumpNativeParams calldata params) external payable;\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Like is ILibStarVault, ILibWarp {\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 ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputSinglePermit(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2LikeExactInputPermit(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV2Router is ILibStarVault, ILibWarp {\n error EthTransferFailed();\n error ZeroAmountOut();\n error IncorrectEthValue();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IUniV3Like is ILibStarVault, ILibUniV3Like, ILibWarp {\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 calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputSinglePermit(\n ExactInputSingleParams calldata params,\n PermitParams calldata permit\n ) external returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams calldata params\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInputPermit(\n ExactInputParams calldata params,\n PermitParams calldata permit\n ) external 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';\nimport {ILibCurve} from '../interfaces/ILibCurve.sol';\nimport {ILibStarVault} from '../interfaces/ILibStarVault.sol';\nimport {ILibUniV3Like} from '../interfaces/ILibUniV3Like.sol';\nimport {ILibWarp} from '../interfaces/ILibWarp.sol';\n\ninterface IWarpLink is ILibCurve, ILibStarVault, ILibUniV3Like, ILibWarp {\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 error InvalidSgReceiverSender();\n error InvalidSgReceiveSrcAddress();\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 calldata params) external payable;\n\n function warpLinkEngagePermit(\n Params calldata params,\n PermitParams calldata permit\n ) external payable;\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3, ICurvePoolKind4} from '../interfaces/external/ICurvePool.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibCurve\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 bool useEth\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 if (useEth) {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy, true);\n } else {\n ICurvePoolKind3(pool).exchange(uint256(i), uint256(j), dx, min_dy);\n }\n } else if (kind == 4) {\n if (underlying) {\n revert UnhandledPoolKind();\n } else {\n ICurvePoolKind4(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibStarVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * NOTE: Events and errors must be copied to ILibStarVault\n */\nlibrary LibStarVault {\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint256 maxFeeBps);\n\n event Fee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 protocolFee\n );\n\n struct State {\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 uint256 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n /**\n * NOTE: Three storage slots used to store all partners addresses and partner tokens were\n * removed to save gas.\n */\n unchecked {\n uint256 storagePosition = uint256(keccak256('diamond.storage.LibStarVault')) + 3;\n\n assembly {\n s.slot := storagePosition\n }\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 protocolFee\n ) internal {\n State storage s = state();\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit Fee(partner, token, partnerFee, protocolFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint256 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 feeProtocol = feeTotal - feePartner;\n\n if (feeProtocol > 0) {\n registerCollectedFee(partner, token, feePartner, feeProtocol);\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\n/**\n * NOTE: Events and errors must be copied to ILibUniV3Like\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 * Whether to use a permit transfer (0 or 1)\n */\n uint256 usePermit;\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 {IStargateComposer} from '../interfaces/external/IStargateComposer.sol';\n\n/**\n * NOTE: Events and errors must be copied to ILibWarp\n */\nlibrary LibWarp {\n event Warp(\n address indexed partner,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 amountIn,\n uint256 amountOut\n );\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateComposer stargateComposer;\n }\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\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 50dcecdb..846ae6c8 100644 --- a/packages/hardhat/package.json +++ b/packages/hardhat/package.json @@ -1,6 +1,6 @@ { "name": "@sifi/hardhat", - "version": "1.26.0", + "version": "1.27.0", "main": "dist/index.js", "types": "dist/index.d.ts", "repository": {