From 23f2db9cc38aee40a02124f247f663711f5efd7c Mon Sep 17 00:00:00 2001 From: Sean Date: Tue, 23 Jul 2024 14:22:03 +0900 Subject: [PATCH] feat: Arbitrage deploy --- deploy/Arbitrage.ts | 10 +- deployments/421614/Arbitrage.json | 481 ++++++++++++++++++ .../e634729b678ce078f381c6f26baf2f0d.json | 174 +++++++ deployments/8453/Arbitrage.json | 481 ++++++++++++++++++ .../e634729b678ce078f381c6f26baf2f0d.json | 174 +++++++ 5 files changed, 1315 insertions(+), 5 deletions(-) create mode 100644 deployments/421614/Arbitrage.json create mode 100644 deployments/421614/solcInputs/e634729b678ce078f381c6f26baf2f0d.json create mode 100644 deployments/8453/Arbitrage.json create mode 100644 deployments/8453/solcInputs/e634729b678ce078f381c6f26baf2f0d.json diff --git a/deploy/Arbitrage.ts b/deploy/Arbitrage.ts index 3fe396e..a9de505 100644 --- a/deploy/Arbitrage.ts +++ b/deploy/Arbitrage.ts @@ -3,7 +3,6 @@ import { DeployFunction } from 'hardhat-deploy/types' import { BOOK_MANAGER, deployWithVerify, SAFE_WALLET } from '../utils' import { getChain, isDevelopmentNetwork } from '@nomicfoundation/hardhat-viem/internal/chains' import { Address } from 'viem' -import { arbitrum } from 'viem/chains' const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployments, getNamedAccounts, network } = hre @@ -14,13 +13,14 @@ const deployFunction: DeployFunction = async function (hre: HardhatRuntimeEnviro return } - let owner: Address = '0x' + let owner: Address if (chain.testnet || isDevelopmentNetwork(chain.id)) { owner = deployer - } else if (chain.id === arbitrum.id) { - owner = SAFE_WALLET[chain.id] // Safe } else { - throw new Error('Unknown chain') + owner = SAFE_WALLET[chain.id] // Safe + if (owner == undefined) { + throw new Error('Unknown chain') + } } await deployWithVerify(hre, 'Arbitrage', [BOOK_MANAGER[chain.id], owner]) diff --git a/deployments/421614/Arbitrage.json b/deployments/421614/Arbitrage.json new file mode 100644 index 0000000..c5bc9f8 --- /dev/null +++ b/deployments/421614/Arbitrage.json @@ -0,0 +1,481 @@ +{ + "address": "0x496c18534115cF3F1421169596dc8cd41335B47c", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "bookManager_", + "type": "address" + }, + { + "internalType": "address", + "name": "initialOwner_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ERC20TransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAccess", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTick", + "type": "error" + }, + { + "inputs": [], + "name": "NativeTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "NotOperator", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyGuardReentrantCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "bits", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintDowncast", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintToInt", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "status", + "type": "bool" + } + ], + "name": "SetOperator", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "BookId", + "name": "id", + "type": "uint192" + }, + { + "internalType": "address", + "name": "router", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "arbitrage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "bookManager", + "outputs": [ + { + "internalType": "contract IBookManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isOperator", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "lockAcquired", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "status", + "type": "bool" + } + ], + "name": "setOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "Currency", + "name": "currency", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xc72e41d6911880469c982d62ac95620b2e57ee07ce9088239c27abe22f064468", + "receipt": { + "to": null, + "from": "0x5F79EE8f8fA862E98201120d83c4eC39D9468D49", + "contractAddress": "0x496c18534115cF3F1421169596dc8cd41335B47c", + "transactionIndex": 1, + "gasUsed": "1709221", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000008000001000000000000000004000000000000000000020000000000000000000800000000010000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000020000040000000000", + "blockHash": "0x4fb99f6084e84db17bba234a6c36591f31cc725342bc51def67427f8b243c2a0", + "transactionHash": "0xc72e41d6911880469c982d62ac95620b2e57ee07ce9088239c27abe22f064468", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 65942822, + "transactionHash": "0xc72e41d6911880469c982d62ac95620b2e57ee07ce9088239c27abe22f064468", + "address": "0x496c18534115cF3F1421169596dc8cd41335B47c", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000005f79ee8f8fa862e98201120d83c4ec39d9468d49" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x4fb99f6084e84db17bba234a6c36591f31cc725342bc51def67427f8b243c2a0" + } + ], + "blockNumber": 65942822, + "cumulativeGasUsed": "1709221", + "status": 1, + "byzantium": true + }, + "args": [ + "0xC528b9ED5d56d1D0d3C18A2342954CE1069138a4", + "0x5F79EE8f8fA862E98201120d83c4eC39D9468D49" + ], + "numDeployments": 1, + "solcInputHash": "e634729b678ce078f381c6f26baf2f0d", + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bookManager_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"initialOwner_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ERC20TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAccess\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTick\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativeTransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotOperator\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"bits\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SafeCastOverflowedUintDowncast\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SafeCastOverflowedUintToInt\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"SetOperator\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"BookId\",\"name\":\"id\",\"type\":\"uint192\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"arbitrage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bookManager\",\"outputs\":[{\"internalType\":\"contract IBookManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isOperator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"lockAcquired\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"setOperator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"Currency\",\"name\":\"currency\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"OwnableInvalidOwner(address)\":[{\"details\":\"The owner is not a valid owner account. (eg. `address(0)`)\"}],\"OwnableUnauthorizedAccount(address)\":[{\"details\":\"The caller account is not authorized to perform an operation.\"}],\"SafeCastOverflowedUintDowncast(uint8,uint256)\":[{\"details\":\"Value doesn't fit in an uint of `bits` size.\"}],\"SafeCastOverflowedUintToInt(uint256)\":[{\"details\":\"An uint value doesn't fit in an int of `bits` size.\"}]},\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"errors\":{\"ERC20TransferFailed()\":[{\"notice\":\"Thrown when an ERC20 transfer fails\"}],\"NativeTransferFailed()\":[{\"notice\":\"Thrown when a native transfer fails\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/Arbitrage.sol\":\"Arbitrage\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Context} from \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initial owner is set to the address provided by the deployer. This can\\n * later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n /**\\n * @dev The caller account is not authorized to perform an operation.\\n */\\n error OwnableUnauthorizedAccount(address account);\\n\\n /**\\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\\n */\\n error OwnableInvalidOwner(address owner);\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\\n */\\n constructor(address initialOwner) {\\n if (initialOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(initialOwner);\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n if (owner() != _msgSender()) {\\n revert OwnableUnauthorizedAccount(_msgSender());\\n }\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n if (newOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable2Step.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Ownable} from \\\"./Ownable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This extension of the {Ownable} contract includes a two-step mechanism to transfer\\n * ownership, where the new owner must call {acceptOwnership} in order to replace the\\n * old one. This can help prevent common mistakes, such as transfers of ownership to\\n * incorrect accounts, or to contracts that are unable to interact with the\\n * permission system.\\n *\\n * The initial owner is specified at deployment time in the constructor for `Ownable`. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2Step is Ownable {\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n if (pendingOwner() != sender) {\\n revert OwnableUnauthorizedAccount(sender);\\n }\\n _transferOwnership(sender);\\n }\\n}\\n\",\"keccak256\":\"0x08b074ae1b12e70ce24d1335086ec5a418934311a6771d9f61fe24d392050e12\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\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 value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens as the allowance of `spender` over the\\n * 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 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` 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 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xee2337af2dc162a973b4be6d3f7c16f06298259e0af48c5470d2839bfa8a22f4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC-721 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\\n * 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 ERC-721 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\\n * {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\\n * 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 ERC-721\\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 address zero.\\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\",\"keccak256\":\"0xe0e3a2099f2e2ce3579dd35548f613928739642058dfec95b1745f93364ce3de\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC721} from \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x37d1aaaa5a2908a09e9dcf56a26ddf762ecf295afb5964695937344fc6802ce1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n function _contextSuffixLength() internal view virtual returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\\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[ERC section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xc859863e3bda7ec3cddf6dafe2ffe91bcbe648d1395b856b839c32ee9617c44c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Value doesn't fit in an uint of `bits` size.\\n */\\n error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\\n\\n /**\\n * @dev An int value doesn't fit in an uint of `bits` size.\\n */\\n error SafeCastOverflowedIntToUint(int256 value);\\n\\n /**\\n * @dev Value doesn't fit in an int of `bits` size.\\n */\\n error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\\n\\n /**\\n * @dev An uint value doesn't fit in an int of `bits` size.\\n */\\n error SafeCastOverflowedUintToInt(uint256 value);\\n\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n if (value > type(uint248).max) {\\n revert SafeCastOverflowedUintDowncast(248, value);\\n }\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n if (value > type(uint240).max) {\\n revert SafeCastOverflowedUintDowncast(240, value);\\n }\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n if (value > type(uint232).max) {\\n revert SafeCastOverflowedUintDowncast(232, value);\\n }\\n return uint232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n if (value > type(uint224).max) {\\n revert SafeCastOverflowedUintDowncast(224, value);\\n }\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n if (value > type(uint216).max) {\\n revert SafeCastOverflowedUintDowncast(216, value);\\n }\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n if (value > type(uint208).max) {\\n revert SafeCastOverflowedUintDowncast(208, value);\\n }\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n if (value > type(uint200).max) {\\n revert SafeCastOverflowedUintDowncast(200, value);\\n }\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n if (value > type(uint192).max) {\\n revert SafeCastOverflowedUintDowncast(192, value);\\n }\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n if (value > type(uint184).max) {\\n revert SafeCastOverflowedUintDowncast(184, value);\\n }\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n if (value > type(uint176).max) {\\n revert SafeCastOverflowedUintDowncast(176, value);\\n }\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n if (value > type(uint168).max) {\\n revert SafeCastOverflowedUintDowncast(168, value);\\n }\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n if (value > type(uint160).max) {\\n revert SafeCastOverflowedUintDowncast(160, value);\\n }\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n if (value > type(uint152).max) {\\n revert SafeCastOverflowedUintDowncast(152, value);\\n }\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n if (value > type(uint144).max) {\\n revert SafeCastOverflowedUintDowncast(144, value);\\n }\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n if (value > type(uint136).max) {\\n revert SafeCastOverflowedUintDowncast(136, value);\\n }\\n return uint136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n if (value > type(uint128).max) {\\n revert SafeCastOverflowedUintDowncast(128, value);\\n }\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n if (value > type(uint120).max) {\\n revert SafeCastOverflowedUintDowncast(120, value);\\n }\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n if (value > type(uint112).max) {\\n revert SafeCastOverflowedUintDowncast(112, value);\\n }\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n if (value > type(uint104).max) {\\n revert SafeCastOverflowedUintDowncast(104, value);\\n }\\n return uint104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n if (value > type(uint96).max) {\\n revert SafeCastOverflowedUintDowncast(96, value);\\n }\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n if (value > type(uint88).max) {\\n revert SafeCastOverflowedUintDowncast(88, value);\\n }\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n if (value > type(uint80).max) {\\n revert SafeCastOverflowedUintDowncast(80, value);\\n }\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n if (value > type(uint72).max) {\\n revert SafeCastOverflowedUintDowncast(72, value);\\n }\\n return uint72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n if (value > type(uint64).max) {\\n revert SafeCastOverflowedUintDowncast(64, value);\\n }\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n if (value > type(uint56).max) {\\n revert SafeCastOverflowedUintDowncast(56, value);\\n }\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n if (value > type(uint48).max) {\\n revert SafeCastOverflowedUintDowncast(48, value);\\n }\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n if (value > type(uint40).max) {\\n revert SafeCastOverflowedUintDowncast(40, value);\\n }\\n return uint40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n if (value > type(uint32).max) {\\n revert SafeCastOverflowedUintDowncast(32, value);\\n }\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n if (value > type(uint24).max) {\\n revert SafeCastOverflowedUintDowncast(24, value);\\n }\\n return uint24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n if (value > type(uint16).max) {\\n revert SafeCastOverflowedUintDowncast(16, value);\\n }\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n if (value > type(uint8).max) {\\n revert SafeCastOverflowedUintDowncast(8, value);\\n }\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n if (value < 0) {\\n revert SafeCastOverflowedIntToUint(value);\\n }\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(248, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(240, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(232, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(224, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(216, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(208, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(200, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(192, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(184, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(176, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(168, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(160, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(152, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(144, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(136, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(128, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(120, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(112, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(104, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(96, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(88, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(80, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(72, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(64, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(56, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(48, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(40, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(32, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(24, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(16, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(8, value);\\n }\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n if (value > uint256(type(int256).max)) {\\n revert SafeCastOverflowedUintToInt(value);\\n }\\n return int256(value);\\n }\\n\\n /**\\n * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\\n */\\n function toUint(bool b) internal pure returns (uint256 u) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n u := iszero(iszero(b))\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8cd59334ed58b8884cd1f775afc9400db702e674e5d6a7a438c655b9de788d7e\",\"license\":\"MIT\"},\"src/Arbitrage.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {Ownable, Ownable2Step} from \\\"@openzeppelin/contracts/access/Ownable2Step.sol\\\";\\nimport {IBookManager} from \\\"v2-core/interfaces/IBookManager.sol\\\";\\nimport {ILocker} from \\\"v2-core/interfaces/ILocker.sol\\\";\\nimport {IHooks} from \\\"v2-core/interfaces/IHooks.sol\\\";\\nimport {BookId, BookIdLibrary} from \\\"v2-core/libraries/BookId.sol\\\";\\nimport {Currency, CurrencyLibrary} from \\\"v2-core/libraries/Currency.sol\\\";\\nimport {FeePolicy, FeePolicyLibrary} from \\\"v2-core/libraries/FeePolicy.sol\\\";\\nimport {Tick, TickLibrary} from \\\"v2-core/libraries/Tick.sol\\\";\\nimport {ReentrancyGuard} from \\\"./libraries/ReentrancyGuard.sol\\\";\\nimport {IArbitrage} from \\\"./interfaces/IArbitrage.sol\\\";\\n\\ncontract Arbitrage is IArbitrage, Ownable2Step, ILocker, ReentrancyGuard {\\n using TickLibrary for Tick;\\n using SafeCast for uint256;\\n using CurrencyLibrary for Currency;\\n using FeePolicyLibrary for FeePolicy;\\n\\n IBookManager public immutable bookManager;\\n\\n mapping(address => bool) public isOperator;\\n\\n modifier onlyOperator() {\\n if (!isOperator[msg.sender]) revert NotOperator();\\n _;\\n }\\n\\n constructor(address bookManager_, address initialOwner_) Ownable(initialOwner_) {\\n bookManager = IBookManager(bookManager_);\\n }\\n\\n function setOperator(address operator, bool status) external onlyOwner {\\n isOperator[operator] = status;\\n emit SetOperator(operator, status);\\n }\\n\\n function lockAcquired(address sender, bytes memory data) external nonReentrant returns (bytes memory) {\\n if (msg.sender != address(bookManager) || sender != address(this)) revert InvalidAccess();\\n address user;\\n BookId id;\\n address router;\\n (user, id, router, data) = abi.decode(data, (address, BookId, address, bytes));\\n\\n IBookManager.BookKey memory key = bookManager.getBookKey(id);\\n uint256 max;\\n bool success;\\n bytes memory returnData;\\n if (key.quote.isNative()) {\\n max = address(bookManager).balance;\\n bookManager.withdraw(key.quote, address(this), max);\\n (success, returnData) = router.call{value: max}(data);\\n } else {\\n IERC20 quote = IERC20(Currency.unwrap(key.quote));\\n max = quote.balanceOf(address(bookManager));\\n quote.approve(router, max);\\n (success, returnData) = router.call(data);\\n quote.approve(router, 0);\\n }\\n if (!success) revert();\\n\\n uint256 quoteAmount = max - key.quote.balanceOfSelf();\\n uint256 baseAmount = key.base.balanceOfSelf();\\n uint256 spentBaseAmount;\\n uint256 price;\\n if (key.takerPolicy.usesQuote()) {\\n quoteAmount = uint256(quoteAmount.toInt256() + key.takerPolicy.calculateFee(quoteAmount, false));\\n price = (quoteAmount << 96) / baseAmount;\\n } else {\\n price = (quoteAmount << 96) / key.takerPolicy.calculateOriginalAmount(baseAmount, false);\\n }\\n\\n while (spentBaseAmount < baseAmount && !bookManager.isEmpty(id)) {\\n Tick tick = bookManager.getHighest(id);\\n if (price >= tick.toPrice()) break; // Did not consider fees.\\n uint256 maxAmount;\\n unchecked {\\n if (key.takerPolicy.usesQuote()) {\\n maxAmount = baseAmount - spentBaseAmount;\\n } else {\\n maxAmount = key.takerPolicy.calculateOriginalAmount(baseAmount - spentBaseAmount, false);\\n }\\n }\\n maxAmount = tick.baseToQuote(maxAmount, false) / key.unitSize;\\n if (maxAmount == 0) break;\\n (, uint256 amount) =\\n bookManager.take(IBookManager.TakeParams({key: key, tick: tick, maxUnit: maxAmount.toUint64()}), \\\"\\\");\\n if (amount == 0) break;\\n spentBaseAmount += amount;\\n }\\n\\n _settleCurrency(user, key.quote);\\n _settleCurrency(user, key.base);\\n\\n return \\\"\\\";\\n }\\n\\n function arbitrage(BookId id, address router, bytes calldata data) external onlyOperator {\\n bookManager.lock(address(this), abi.encode(msg.sender, id, router, data));\\n }\\n\\n function _settleCurrency(address user, Currency currency) internal {\\n int256 currencyDelta = -bookManager.getCurrencyDelta(address(this), currency);\\n if (currencyDelta > 0) {\\n currency.transfer(address(bookManager), uint256(currencyDelta));\\n }\\n bookManager.settle(currency);\\n currency.transfer(user, currency.balanceOfSelf());\\n }\\n\\n function withdrawToken(Currency currency, uint256 amount, address recipient) external onlyOwner {\\n currency.transfer(recipient, amount);\\n }\\n\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xbefc5d0001a721e18fbc562ad464d29b02b06183087315578ee72e7242ab7fee\",\"license\":\"GPL-2.0-or-later\"},\"src/interfaces/IArbitrage.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.0;\\n\\nimport {BookId} from \\\"v2-core/libraries/BookId.sol\\\";\\nimport {Currency} from \\\"v2-core/libraries/Currency.sol\\\";\\n\\ninterface IArbitrage {\\n error InvalidAccess();\\n error NotOperator();\\n\\n event SetOperator(address indexed operator, bool status);\\n\\n function setOperator(address operator, bool status) external;\\n\\n function arbitrage(BookId id, address router, bytes calldata data) external;\\n\\n function withdrawToken(Currency currency, uint256 amount, address recipient) external;\\n}\\n\",\"keccak256\":\"0x6a3388787f1777d2b29ee3a57e742acc79f2dbdd6aebdd4bbe9c2723b024682c\",\"license\":\"UNLICENSED\"},\"src/libraries/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.24;\\n\\nabstract contract ReentrancyGuard {\\n // uint256(keccak256(\\\"ReentrancyGuard\\\")) - 1\\n uint256 internal constant REENTRANCY_GUARD_SLOT = 0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4;\\n\\n error ReentrancyGuardReentrantCall();\\n\\n modifier nonReentrant() {\\n _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n if (_reentrancyGuardEntered()) {\\n revert ReentrancyGuardReentrantCall();\\n }\\n assembly {\\n // Any calls to nonReentrant after this point will fail\\n tstore(REENTRANCY_GUARD_SLOT, 1)\\n }\\n }\\n\\n function _nonReentrantAfter() private {\\n assembly {\\n tstore(REENTRANCY_GUARD_SLOT, 0)\\n }\\n }\\n\\n function _reentrancyGuardEntered() internal view returns (bool isEntered) {\\n assembly {\\n isEntered := tload(REENTRANCY_GUARD_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4a29368336cca301ffb393ab2b667b311cca443f888bc4d2593261f47114ea1b\",\"license\":\"GPL-2.0-or-later\"},\"v2-core/interfaces/IBookManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport {BookId} from \\\"../libraries/BookId.sol\\\";\\nimport {Currency} from \\\"../libraries/Currency.sol\\\";\\nimport {OrderId} from \\\"../libraries/OrderId.sol\\\";\\nimport {Tick} from \\\"../libraries/Tick.sol\\\";\\nimport {FeePolicy} from \\\"../libraries/FeePolicy.sol\\\";\\nimport {IERC721Permit} from \\\"./IERC721Permit.sol\\\";\\nimport {IHooks} from \\\"./IHooks.sol\\\";\\n\\n/**\\n * @title IBookManager\\n * @notice The interface for the BookManager contract\\n */\\ninterface IBookManager is IERC721Metadata, IERC721Permit {\\n error InvalidUnitSize();\\n error InvalidFeePolicy();\\n error InvalidProvider(address provider);\\n error LockedBy(address locker, address hook);\\n error CurrencyNotSettled();\\n\\n /**\\n * @notice Event emitted when a new book is opened\\n * @param id The book id\\n * @param base The base currency\\n * @param quote The quote currency\\n * @param unitSize The unit size of the book\\n * @param makerPolicy The maker fee policy\\n * @param takerPolicy The taker fee policy\\n * @param hooks The hooks contract\\n */\\n event Open(\\n BookId indexed id,\\n Currency indexed base,\\n Currency indexed quote,\\n uint64 unitSize,\\n FeePolicy makerPolicy,\\n FeePolicy takerPolicy,\\n IHooks hooks\\n );\\n\\n /**\\n * @notice Event emitted when a new order is made\\n * @param bookId The book id\\n * @param user The user address\\n * @param tick The order tick\\n * @param orderIndex The order index\\n * @param unit The order unit\\n * @param provider The provider address\\n */\\n event Make(\\n BookId indexed bookId, address indexed user, Tick tick, uint256 orderIndex, uint64 unit, address provider\\n );\\n\\n /**\\n * @notice Event emitted when an order is taken\\n * @param bookId The book id\\n * @param user The user address\\n * @param tick The order tick\\n * @param unit The order unit\\n */\\n event Take(BookId indexed bookId, address indexed user, Tick tick, uint64 unit);\\n\\n /**\\n * @notice Event emitted when an order is canceled\\n * @param orderId The order id\\n * @param unit The canceled unit\\n */\\n event Cancel(OrderId indexed orderId, uint64 unit);\\n\\n /**\\n * @notice Event emitted when an order is claimed\\n * @param orderId The order id\\n * @param unit The claimed unit\\n */\\n event Claim(OrderId indexed orderId, uint64 unit);\\n\\n /**\\n * @notice Event emitted when a provider is whitelisted\\n * @param provider The provider address\\n */\\n event Whitelist(address indexed provider);\\n\\n /**\\n * @notice Event emitted when a provider is delisted\\n * @param provider The provider address\\n */\\n event Delist(address indexed provider);\\n\\n /**\\n * @notice Event emitted when a provider collects fees\\n * @param provider The provider address\\n * @param recipient The recipient address\\n * @param currency The currency\\n * @param amount The collected amount\\n */\\n event Collect(address indexed provider, address indexed recipient, Currency indexed currency, uint256 amount);\\n\\n /**\\n * @notice Event emitted when new default provider is set\\n * @param newDefaultProvider The new default provider address\\n */\\n event SetDefaultProvider(address indexed newDefaultProvider);\\n\\n /**\\n * @notice This structure represents a unique identifier for a book in the BookManager.\\n * @param base The base currency of the book\\n * @param unitSize The unit size of the book\\n * @param quote The quote currency of the book\\n * @param makerPolicy The maker fee policy of the book\\n * @param hooks The hooks contract of the book\\n * @param takerPolicy The taker fee policy of the book\\n */\\n struct BookKey {\\n Currency base;\\n uint64 unitSize;\\n Currency quote;\\n FeePolicy makerPolicy;\\n IHooks hooks;\\n FeePolicy takerPolicy;\\n }\\n\\n /**\\n * @notice Returns the base URI\\n * @return The base URI\\n */\\n function baseURI() external view returns (string memory);\\n\\n /**\\n * @notice Returns the contract URI\\n * @return The contract URI\\n */\\n function contractURI() external view returns (string memory);\\n\\n /**\\n * @notice Returns the default provider\\n * @return The default provider\\n */\\n function defaultProvider() external view returns (address);\\n\\n /**\\n * @notice Returns the total reserves of a given currency\\n * @param currency The currency in question\\n * @return The total reserves amount\\n */\\n function reservesOf(Currency currency) external view returns (uint256);\\n\\n /**\\n * @notice Checks if a provider is whitelisted\\n * @param provider The address of the provider\\n * @return True if the provider is whitelisted, false otherwise\\n */\\n function isWhitelisted(address provider) external view returns (bool);\\n\\n /**\\n * @notice Verifies if an owner has authorized a spender for a token\\n * @param owner The address of the token owner\\n * @param spender The address of the spender\\n * @param tokenId The token ID\\n */\\n function checkAuthorized(address owner, address spender, uint256 tokenId) external view;\\n\\n /**\\n * @notice Calculates the amount owed to a provider in a given currency\\n * @param provider The provider's address\\n * @param currency The currency in question\\n * @return The owed amount\\n */\\n function tokenOwed(address provider, Currency currency) external view returns (uint256);\\n\\n /**\\n * @notice Calculates the currency balance changes for a given locker\\n * @param locker The address of the locker\\n * @param currency The currency in question\\n * @return The net change in currency balance\\n */\\n function getCurrencyDelta(address locker, Currency currency) external view returns (int256);\\n\\n /**\\n * @notice Retrieves the book key for a given book ID\\n * @param id The book ID\\n * @return The book key\\n */\\n function getBookKey(BookId id) external view returns (BookKey memory);\\n\\n /**\\n * @notice This structure represents a current status for an order in the BookManager.\\n * @param provider The provider of the order\\n * @param open The open unit of the order\\n * @param claimable The claimable unit of the order\\n */\\n struct OrderInfo {\\n address provider;\\n uint64 open;\\n uint64 claimable;\\n }\\n\\n /**\\n * @notice Provides information about an order\\n * @param id The order ID\\n * @return Order information including provider, open status, and claimable unit\\n */\\n function getOrder(OrderId id) external view returns (OrderInfo memory);\\n\\n /**\\n * @notice Retrieves the locker and caller addresses for a given lock\\n * @param i The index of the lock\\n * @return locker The locker's address\\n * @return lockCaller The caller's address\\n */\\n function getLock(uint256 i) external view returns (address locker, address lockCaller);\\n\\n /**\\n * @notice Provides the lock data\\n * @return The lock data including necessary numeric values\\n */\\n function getLockData() external view returns (uint128, uint128);\\n\\n /**\\n * @notice Returns the depth of a given book ID and tick\\n * @param id The book ID\\n * @param tick The tick\\n * @return The depth of the tick\\n */\\n function getDepth(BookId id, Tick tick) external view returns (uint64);\\n\\n /**\\n * @notice Retrieves the highest tick for a given book ID\\n * @param id The book ID\\n * @return tick The highest tick\\n */\\n function getHighest(BookId id) external view returns (Tick tick);\\n\\n /**\\n * @notice Finds the maximum tick less than a specified tick in a book\\n * @dev Returns `Tick.wrap(type(int24).min)` if the specified tick is the lowest\\n * @param id The book ID\\n * @param tick The specified tick\\n * @return The next lower tick\\n */\\n function maxLessThan(BookId id, Tick tick) external view returns (Tick);\\n\\n /**\\n * @notice Checks if a book is opened\\n * @param id The book ID\\n * @return True if the book is opened, false otherwise\\n */\\n function isOpened(BookId id) external view returns (bool);\\n\\n /**\\n * @notice Checks if a book is empty\\n * @param id The book ID\\n * @return True if the book is empty, false otherwise\\n */\\n function isEmpty(BookId id) external view returns (bool);\\n\\n /**\\n * @notice Encodes a BookKey into a BookId\\n * @param key The BookKey to encode\\n * @return The encoded BookId\\n */\\n function encodeBookKey(BookKey calldata key) external pure returns (BookId);\\n\\n /**\\n * @notice Loads a value from a specific storage slot\\n * @param slot The storage slot\\n * @return The value in the slot\\n */\\n function load(bytes32 slot) external view returns (bytes32);\\n\\n /**\\n * @notice Loads a sequence of values starting from a specific slot\\n * @param startSlot The starting slot\\n * @param nSlot The number of slots to load\\n * @return The sequence of values\\n */\\n function load(bytes32 startSlot, uint256 nSlot) external view returns (bytes memory);\\n\\n /**\\n * @notice Opens a new book\\n * @param key The book key\\n * @param hookData The hook data\\n */\\n function open(BookKey calldata key, bytes calldata hookData) external;\\n\\n /**\\n * @notice Locks a book manager function\\n * @param locker The locker address\\n * @param data The lock data\\n * @return The lock return data\\n */\\n function lock(address locker, bytes calldata data) external returns (bytes memory);\\n\\n /**\\n * @notice This structure represents the parameters for making an order.\\n * @param key The book key for the order\\n * @param tick The tick for the order\\n * @param unit The unit for the order. Times key.unitSize to get actual bid amount.\\n * @param provider The provider for the order. The limit order service provider address to collect fees.\\n */\\n struct MakeParams {\\n BookKey key;\\n Tick tick;\\n uint64 unit;\\n address provider;\\n }\\n\\n /**\\n * @notice Make a limit order\\n * @param params The order parameters\\n * @param hookData The hook data\\n * @return id The order id. Returns 0 if the order is not settled\\n * @return quoteAmount The amount of quote currency to be paid\\n */\\n function make(MakeParams calldata params, bytes calldata hookData)\\n external\\n returns (OrderId id, uint256 quoteAmount);\\n\\n /**\\n * @notice This structure represents the parameters for taking orders in the specified tick.\\n * @param key The book key for the order\\n * @param tick The tick for the order\\n * @param maxUnit The max unit to take\\n */\\n struct TakeParams {\\n BookKey key;\\n Tick tick;\\n uint64 maxUnit;\\n }\\n\\n /**\\n * @notice Take a limit order at specific tick\\n * @param params The order parameters\\n * @param hookData The hook data\\n * @return quoteAmount The amount of quote currency to be received\\n * @return baseAmount The amount of base currency to be paid\\n */\\n function take(TakeParams calldata params, bytes calldata hookData)\\n external\\n returns (uint256 quoteAmount, uint256 baseAmount);\\n\\n /**\\n * @notice This structure represents the parameters for canceling an order.\\n * @param id The order id for the order\\n * @param toUnit The remaining open unit for the order after cancellation. Must not exceed the current open unit.\\n */\\n struct CancelParams {\\n OrderId id;\\n uint64 toUnit;\\n }\\n\\n /**\\n * @notice Cancel a limit order\\n * @param params The order parameters\\n * @param hookData The hook data\\n * @return canceledAmount The amount of quote currency canceled\\n */\\n function cancel(CancelParams calldata params, bytes calldata hookData) external returns (uint256 canceledAmount);\\n\\n /**\\n * @notice Claims an order\\n * @param id The order ID\\n * @param hookData The hook data\\n * @return claimedAmount The amount claimed\\n */\\n function claim(OrderId id, bytes calldata hookData) external returns (uint256 claimedAmount);\\n\\n /**\\n * @notice Collects fees from a provider\\n * @param recipient The recipient address\\n * @param currency The currency\\n * @return The collected amount\\n */\\n function collect(address recipient, Currency currency) external returns (uint256);\\n\\n /**\\n * @notice Withdraws a currency\\n * @param currency The currency\\n * @param to The recipient address\\n * @param amount The amount\\n */\\n function withdraw(Currency currency, address to, uint256 amount) external;\\n\\n /**\\n * @notice Settles a currency\\n * @param currency The currency\\n * @return The settled amount\\n */\\n function settle(Currency currency) external payable returns (uint256);\\n\\n /**\\n * @notice Whitelists a provider\\n * @param provider The provider address\\n */\\n function whitelist(address provider) external;\\n\\n /**\\n * @notice Delists a provider\\n * @param provider The provider address\\n */\\n function delist(address provider) external;\\n\\n /**\\n * @notice Sets the default provider\\n * @param newDefaultProvider The new default provider address\\n */\\n function setDefaultProvider(address newDefaultProvider) external;\\n}\\n\",\"keccak256\":\"0xda8dffc751ac3554033e084919f1e431eb2585c80e1e30b9a0198366a8607086\",\"license\":\"MIT\"},\"v2-core/interfaces/IERC721Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/**\\n * @title IERC721Permit\\n * @notice An interface for the ERC721 permit extension\\n */\\ninterface IERC721Permit is IERC721 {\\n error InvalidSignature();\\n error PermitExpired();\\n\\n /**\\n * @notice The EIP-712 typehash for the permit struct used by the contract\\n */\\n function PERMIT_TYPEHASH() external pure returns (bytes32);\\n\\n /**\\n * @notice The EIP-712 domain separator for this contract\\n */\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n\\n /**\\n * @notice Approve the spender to transfer the given tokenId\\n * @param spender The address to approve\\n * @param tokenId The tokenId to approve\\n * @param deadline The deadline for the signature\\n * @param v The recovery id of the signature\\n * @param r The r value of the signature\\n * @param s The s value of the signature\\n */\\n function permit(address spender, uint256 tokenId, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\\n\\n /**\\n * @notice Get the current nonce for a token\\n * @param tokenId The tokenId to get the nonce for\\n * @return The current nonce\\n */\\n function nonces(uint256 tokenId) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xd6baab4710fa674981395f428bd6550c4e288ac44a1a5d38c2a58fd67234d57e\",\"license\":\"MIT\"},\"v2-core/interfaces/IHooks.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.20;\\n\\nimport {IBookManager} from \\\"./IBookManager.sol\\\";\\nimport {OrderId} from \\\"../libraries/OrderId.sol\\\";\\n\\n/**\\n * @title IHooks\\n * @notice Interface for the hooks contract\\n */\\ninterface IHooks {\\n /**\\n * @notice Hook called before opening a new book\\n * @param sender The sender of the open transaction\\n * @param key The key of the book being opened\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function beforeOpen(address sender, IBookManager.BookKey calldata key, bytes calldata hookData)\\n external\\n returns (bytes4);\\n\\n /**\\n * @notice Hook called after opening a new book\\n * @param sender The sender of the open transaction\\n * @param key The key of the book being opened\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function afterOpen(address sender, IBookManager.BookKey calldata key, bytes calldata hookData)\\n external\\n returns (bytes4);\\n\\n /**\\n * @notice Hook called before making a new order\\n * @param sender The sender of the make transaction\\n * @param params The parameters of the make transaction\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function beforeMake(address sender, IBookManager.MakeParams calldata params, bytes calldata hookData)\\n external\\n returns (bytes4);\\n\\n /**\\n * @notice Hook called after making a new order\\n * @param sender The sender of the make transaction\\n * @param params The parameters of the make transaction\\n * @param orderId The id of the order that was made\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function afterMake(\\n address sender,\\n IBookManager.MakeParams calldata params,\\n OrderId orderId,\\n bytes calldata hookData\\n ) external returns (bytes4);\\n\\n /**\\n * @notice Hook called before taking an order\\n * @param sender The sender of the take transaction\\n * @param params The parameters of the take transaction\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function beforeTake(address sender, IBookManager.TakeParams calldata params, bytes calldata hookData)\\n external\\n returns (bytes4);\\n\\n /**\\n * @notice Hook called after taking an order\\n * @param sender The sender of the take transaction\\n * @param params The parameters of the take transaction\\n * @param takenUnit The unit that was taken\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function afterTake(\\n address sender,\\n IBookManager.TakeParams calldata params,\\n uint64 takenUnit,\\n bytes calldata hookData\\n ) external returns (bytes4);\\n\\n /**\\n * @notice Hook called before canceling an order\\n * @param sender The sender of the cancel transaction\\n * @param params The parameters of the cancel transaction\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function beforeCancel(address sender, IBookManager.CancelParams calldata params, bytes calldata hookData)\\n external\\n returns (bytes4);\\n\\n /**\\n * @notice Hook called after canceling an order\\n * @param sender The sender of the cancel transaction\\n * @param params The parameters of the cancel transaction\\n * @param canceledUnit The unit that was canceled\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function afterCancel(\\n address sender,\\n IBookManager.CancelParams calldata params,\\n uint64 canceledUnit,\\n bytes calldata hookData\\n ) external returns (bytes4);\\n\\n /**\\n * @notice Hook called before claiming an order\\n * @param sender The sender of the claim transaction\\n * @param orderId The id of the order being claimed\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function beforeClaim(address sender, OrderId orderId, bytes calldata hookData) external returns (bytes4);\\n\\n /**\\n * @notice Hook called after claiming an order\\n * @param sender The sender of the claim transaction\\n * @param orderId The id of the order being claimed\\n * @param claimedUnit The unit that was claimed\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function afterClaim(address sender, OrderId orderId, uint64 claimedUnit, bytes calldata hookData)\\n external\\n returns (bytes4);\\n}\\n\",\"keccak256\":\"0xbff95e07debd7d51cb3aa79172fd3c31efb57cea1c03d21b5740a565198d8343\",\"license\":\"MIT\"},\"v2-core/interfaces/ILocker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ILocker\\n * @notice Interface for the locker contract\\n */\\ninterface ILocker {\\n /**\\n * @notice Called by the book manager on `msg.sender` when a lock is acquired\\n * @param data The data that was passed to the call to lock\\n * @return Any data that you want to be returned from the lock call\\n */\\n function lockAcquired(address lockCaller, bytes calldata data) external returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x664833ea7804ad5cbbe89f5b36169c6a2c19ef577c1dfb9418ddea290ed19106\",\"license\":\"MIT\"},\"v2-core/libraries/BookId.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.20;\\n\\nimport {IBookManager} from \\\"../interfaces/IBookManager.sol\\\";\\n\\ntype BookId is uint192;\\n\\nlibrary BookIdLibrary {\\n function toId(IBookManager.BookKey memory bookKey) internal pure returns (BookId id) {\\n bytes32 hash = keccak256(abi.encode(bookKey));\\n assembly {\\n id := and(hash, 0xffffffffffffffffffffffffffffffffffffffffffffffff)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x60f9ed99dfb9a5ce14c29359a5ad8b43de0c756e44b2e5f581e8ea6db7cacbeb\",\"license\":\"GPL-2.0-or-later\"},\"v2-core/libraries/Currency.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ntype Currency is address;\\n\\n/// @title CurrencyLibrary\\n/// @dev This library allows for transferring and holding native tokens and ERC20 tokens\\nlibrary CurrencyLibrary {\\n using CurrencyLibrary for Currency;\\n\\n /// @notice Thrown when a native transfer fails\\n error NativeTransferFailed();\\n\\n /// @notice Thrown when an ERC20 transfer fails\\n error ERC20TransferFailed();\\n\\n Currency public constant NATIVE = Currency.wrap(address(0));\\n\\n function transfer(Currency currency, address to, uint256 amount) internal {\\n // implementation from\\n // https://github.com/transmissions11/solmate/blob/e8f96f25d48fe702117ce76c79228ca4f20206cb/src/utils/SafeTransferLib.sol\\n\\n bool success;\\n if (currency.isNative()) {\\n assembly {\\n // Transfer the ETH and store if it succeeded or not.\\n success := call(gas(), to, amount, 0, 0, 0, 0)\\n }\\n\\n if (!success) revert NativeTransferFailed();\\n } else {\\n assembly {\\n // Get a pointer to some free memory.\\n let freeMemoryPointer := mload(0x40)\\n\\n // Write the abi-encoded calldata into memory, beginning with the function selector.\\n mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\\n mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \\\"to\\\" argument.\\n mstore(add(freeMemoryPointer, 36), amount) // Append the \\\"amount\\\" argument. Masking not required as it's a full 32 byte type.\\n\\n success :=\\n and(\\n // Set success to whether the call reverted, if not we check it either\\n // returned exactly 1 (can't just be non-zero data), or had no return data.\\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\\n // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\\n // Counterintuitively, this call must be positioned second to the or() call in the\\n // surrounding and() call or else returndatasize() will be zero during the computation.\\n call(gas(), currency, 0, freeMemoryPointer, 68, 0, 32)\\n )\\n }\\n\\n if (!success) revert ERC20TransferFailed();\\n }\\n }\\n\\n function balanceOfSelf(Currency currency) internal view returns (uint256) {\\n if (currency.isNative()) return address(this).balance;\\n else return IERC20(Currency.unwrap(currency)).balanceOf(address(this));\\n }\\n\\n function equals(Currency currency, Currency other) internal pure returns (bool) {\\n return Currency.unwrap(currency) == Currency.unwrap(other);\\n }\\n\\n function isNative(Currency currency) internal pure returns (bool) {\\n return Currency.unwrap(currency) == Currency.unwrap(NATIVE);\\n }\\n\\n function toId(Currency currency) internal pure returns (uint256) {\\n return uint160(Currency.unwrap(currency));\\n }\\n\\n function fromId(uint256 id) internal pure returns (Currency) {\\n return Currency.wrap(address(uint160(id)));\\n }\\n}\\n\",\"keccak256\":\"0xf04f76015a51981ad0f84fd3ebb0a4eb6c31685604c22584669915aa8dd7ac54\",\"license\":\"GPL-2.0-or-later\"},\"v2-core/libraries/FeePolicy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"./Math.sol\\\";\\n\\ntype FeePolicy is uint24;\\n\\nlibrary FeePolicyLibrary {\\n uint256 internal constant RATE_PRECISION = 10 ** 6;\\n int256 internal constant MAX_FEE_RATE = 500000;\\n int256 internal constant MIN_FEE_RATE = -500000;\\n\\n uint256 internal constant RATE_MASK = 0x7fffff; // 23 bits\\n\\n error InvalidFeePolicy();\\n\\n function encode(bool usesQuote_, int24 rate_) internal pure returns (FeePolicy feePolicy) {\\n if (rate_ > MAX_FEE_RATE || rate_ < MIN_FEE_RATE) {\\n revert InvalidFeePolicy();\\n }\\n\\n uint256 mask = usesQuote_ ? 1 << 23 : 0;\\n assembly {\\n feePolicy := or(mask, add(and(rate_, 0xffffff), MAX_FEE_RATE))\\n }\\n }\\n\\n function isValid(FeePolicy self) internal pure returns (bool) {\\n int24 r = rate(self);\\n\\n return !(r > MAX_FEE_RATE || r < MIN_FEE_RATE);\\n }\\n\\n function usesQuote(FeePolicy self) internal pure returns (bool f) {\\n assembly {\\n f := shr(23, self)\\n }\\n }\\n\\n function rate(FeePolicy self) internal pure returns (int24 r) {\\n assembly {\\n r := sub(and(self, RATE_MASK), MAX_FEE_RATE)\\n }\\n }\\n\\n function calculateFee(FeePolicy self, uint256 amount, bool reverseRounding) internal pure returns (int256 fee) {\\n int24 r = rate(self);\\n\\n bool positive = r > 0;\\n uint256 absRate;\\n unchecked {\\n absRate = uint256(uint24(positive ? r : -r));\\n }\\n // @dev absFee must be less than type(int256).max\\n uint256 absFee = Math.divide(amount * absRate, RATE_PRECISION, reverseRounding ? !positive : positive);\\n fee = positive ? int256(absFee) : -int256(absFee);\\n }\\n\\n function calculateOriginalAmount(FeePolicy self, uint256 amount, bool reverseFee)\\n internal\\n pure\\n returns (uint256 originalAmount)\\n {\\n int24 r = rate(self);\\n\\n bool positive = r > 0;\\n uint256 divider;\\n assembly {\\n if reverseFee { r := sub(0, r) }\\n divider := add(RATE_PRECISION, r)\\n }\\n originalAmount = Math.divide(amount * RATE_PRECISION, divider, positive);\\n }\\n}\\n\",\"keccak256\":\"0x91f98ffef9d8a0bb460bcbc31d10820d9a1bee9bbf3df04eef23ca2937a4a26a\",\"license\":\"GPL-2.0-or-later\"},\"v2-core/libraries/Math.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.0;\\n\\nlibrary Math {\\n function divide(uint256 a, uint256 b, bool roundingUp) internal pure returns (uint256 ret) {\\n // In the OrderBook contract code, b is never zero.\\n assembly {\\n ret := add(div(a, b), and(gt(mod(a, b), 0), roundingUp))\\n }\\n }\\n\\n /// @dev Returns `ln(x)`, denominated in `WAD`.\\n /// Credit to Remco Bloemen under MIT license: https://2\\u03c0.com/22/exp-ln\\n function lnWad(int256 x) internal pure returns (int256 r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n // We want to convert `x` from `10**18` fixed point to `2**96` fixed point.\\n // We do this by multiplying by `2**96 / 10**18`. But since\\n // `ln(x * C) = ln(x) + ln(C)`, we can simply do nothing here\\n // and add `ln(2**96 / 10**18)` at the end.\\n\\n // Compute `k = log2(x) - 96`, `r = 159 - k = 255 - log2(x) = 255 ^ log2(x)`.\\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\\n r := or(r, shl(3, lt(0xff, shr(r, x))))\\n // We place the check here for more optimal stack operations.\\n if iszero(sgt(x, 0)) {\\n mstore(0x00, 0x1615e638) // `LnWadUndefined()`.\\n revert(0x1c, 0x04)\\n }\\n // forgefmt: disable-next-item\\n r := xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),\\n 0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff))\\n\\n // Reduce range of x to (1, 2) * 2**96\\n // ln(2^k * x) = k * ln(2) + ln(x)\\n x := shr(159, shl(r, x))\\n\\n // Evaluate using a (8, 8)-term rational approximation.\\n // `p` is made monic, we will multiply by a scale factor later.\\n // forgefmt: disable-next-item\\n let p := sub( // This heavily nested expression is to avoid stack-too-deep for via-ir.\\n sar(96, mul(add(43456485725739037958740375743393,\\n sar(96, mul(add(24828157081833163892658089445524,\\n sar(96, mul(add(3273285459638523848632254066296,\\n x), x))), x))), x)), 11111509109440967052023855526967)\\n p := sub(sar(96, mul(p, x)), 45023709667254063763336534515857)\\n p := sub(sar(96, mul(p, x)), 14706773417378608786704636184526)\\n p := sub(mul(p, x), shl(96, 795164235651350426258249787498))\\n // We leave `p` in `2**192` basis so we don't need to scale it back up for the division.\\n\\n // `q` is monic by convention.\\n let q := add(5573035233440673466300451813936, x)\\n q := add(71694874799317883764090561454958, sar(96, mul(x, q)))\\n q := add(283447036172924575727196451306956, sar(96, mul(x, q)))\\n q := add(401686690394027663651624208769553, sar(96, mul(x, q)))\\n q := add(204048457590392012362485061816622, sar(96, mul(x, q)))\\n q := add(31853899698501571402653359427138, sar(96, mul(x, q)))\\n q := add(909429971244387300277376558375, sar(96, mul(x, q)))\\n\\n // `p / q` is in the range `(0, 0.125) * 2**96`.\\n\\n // Finalization, we need to:\\n // - Multiply by the scale factor `s = 5.549\\u2026`.\\n // - Add `ln(2**96 / 10**18)`.\\n // - Add `k * ln(2)`.\\n // - Multiply by `10**18 / 2**96 = 5**18 >> 78`.\\n\\n // The q polynomial is known not to have zeros in the domain.\\n // No scaling required because p is already `2**96` too large.\\n p := sdiv(p, q)\\n // Multiply by the scaling factor: `s * 5**18 * 2**96`, base is now `5**18 * 2**192`.\\n p := mul(1677202110996718588342820967067443963516166, p)\\n // Add `ln(2) * k * 5**18 * 2**192`.\\n // forgefmt: disable-next-item\\n p := add(mul(16597577552685614221487285958193947469193820559219878177908093499208371, sub(159, r)), p)\\n // Base conversion: mul `2**96 / (5**18 * 2**192)`.\\n r := sdiv(p, 302231454903657293676544000000000000000000)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb2dc502dd66a9e36e6c4bb8c4fb3d21120f9f0ff7a934dcfe21ec820cac72275\",\"license\":\"GPL-2.0-or-later\"},\"v2-core/libraries/OrderId.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.0;\\n\\nimport {Tick} from \\\"./Tick.sol\\\";\\nimport {BookId} from \\\"./BookId.sol\\\";\\n\\ntype OrderId is uint256;\\n\\nlibrary OrderIdLibrary {\\n /**\\n * @dev Encode the order id.\\n * @param bookId The book id.\\n * @param tick The tick.\\n * @param index The index.\\n * @return id The order id.\\n */\\n function encode(BookId bookId, Tick tick, uint40 index) internal pure returns (OrderId id) {\\n // @dev If we just use tick at the assembly code, the code will convert tick into bytes32.\\n // e.g. When index == -2, the shifted value( shl(40, tick) ) will be\\n // 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000 instead of 0xfffffffe0000000000\\n // Therefore, we have to safely cast tick into uint256 first.\\n uint256 _tick = uint256(uint24(Tick.unwrap(tick)));\\n assembly {\\n id := add(index, add(shl(40, _tick), shl(64, bookId)))\\n }\\n }\\n\\n function decode(OrderId id) internal pure returns (BookId bookId, Tick tick, uint40 index) {\\n assembly {\\n bookId := shr(64, id)\\n tick := and(shr(40, id), 0xffffff)\\n index := and(id, 0xffffffffff)\\n }\\n }\\n\\n function getBookId(OrderId id) internal pure returns (BookId bookId) {\\n assembly {\\n bookId := shr(64, id)\\n }\\n }\\n\\n function getTick(OrderId id) internal pure returns (Tick tick) {\\n assembly {\\n tick := and(shr(40, id), 0xffffff)\\n }\\n }\\n\\n function getIndex(OrderId id) internal pure returns (uint40 index) {\\n assembly {\\n index := and(id, 0xffffffffff)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x78c384badc4971d774987c6f5bce9d578712c7469688735b3c1eafaf2e748fe6\",\"license\":\"GPL-2.0-or-later\"},\"v2-core/libraries/Tick.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"./Math.sol\\\";\\n\\ntype Tick is int24;\\n\\nlibrary TickLibrary {\\n using Math for *;\\n using TickLibrary for Tick;\\n\\n error InvalidTick();\\n error InvalidPrice();\\n error TickOverflow();\\n\\n int24 internal constant MAX_TICK = 2 ** 19 - 1;\\n int24 internal constant MIN_TICK = -MAX_TICK;\\n\\n uint256 internal constant MIN_PRICE = 1350587;\\n uint256 internal constant MAX_PRICE = 4647684107270898330752324302845848816923571339324334;\\n\\n uint256 private constant _R0 = 0xfff97272373d413259a46990;\\n uint256 private constant _R1 = 0xfff2e50f5f656932ef12357c;\\n uint256 private constant _R2 = 0xffe5caca7e10e4e61c3624ea;\\n uint256 private constant _R3 = 0xffcb9843d60f6159c9db5883;\\n uint256 private constant _R4 = 0xff973b41fa98c081472e6896;\\n uint256 private constant _R5 = 0xff2ea16466c96a3843ec78b3;\\n uint256 private constant _R6 = 0xfe5dee046a99a2a811c461f1;\\n uint256 private constant _R7 = 0xfcbe86c7900a88aedcffc83b;\\n uint256 private constant _R8 = 0xf987a7253ac413176f2b074c;\\n uint256 private constant _R9 = 0xf3392b0822b70005940c7a39;\\n uint256 private constant _R10 = 0xe7159475a2c29b7443b29c7f;\\n uint256 private constant _R11 = 0xd097f3bdfd2022b8845ad8f7;\\n uint256 private constant _R12 = 0xa9f746462d870fdf8a65dc1f;\\n uint256 private constant _R13 = 0x70d869a156d2a1b890bb3df6;\\n uint256 private constant _R14 = 0x31be135f97d08fd981231505;\\n uint256 private constant _R15 = 0x9aa508b5b7a84e1c677de54;\\n uint256 private constant _R16 = 0x5d6af8dedb81196699c329;\\n uint256 private constant _R17 = 0x2216e584f5fa1ea92604;\\n uint256 private constant _R18 = 0x48a170391f7dc42;\\n uint256 private constant _R19 = 0x149b34;\\n\\n function validateTick(Tick tick) internal pure {\\n if (Tick.unwrap(tick) > MAX_TICK || Tick.unwrap(tick) < MIN_TICK) revert InvalidTick();\\n }\\n\\n modifier validatePrice(uint256 price) {\\n if (price > MAX_PRICE || price < MIN_PRICE) revert InvalidPrice();\\n _;\\n }\\n\\n function fromPrice(uint256 price) internal pure validatePrice(price) returns (Tick) {\\n unchecked {\\n int24 tick = int24((int256(price).lnWad() * 42951820407860) / 2 ** 128);\\n if (toPrice(Tick.wrap(tick)) > price) return Tick.wrap(tick - 1);\\n return Tick.wrap(tick);\\n }\\n }\\n\\n function toPrice(Tick tick) internal pure returns (uint256 price) {\\n validateTick(tick);\\n int24 tickValue = Tick.unwrap(tick);\\n uint256 absTick = uint24(tickValue < 0 ? -tickValue : tickValue);\\n\\n unchecked {\\n if (absTick & 0x1 != 0) price = _R0;\\n else price = 1 << 96;\\n if (absTick & 0x2 != 0) price = (price * _R1) >> 96;\\n if (absTick & 0x4 != 0) price = (price * _R2) >> 96;\\n if (absTick & 0x8 != 0) price = (price * _R3) >> 96;\\n if (absTick & 0x10 != 0) price = (price * _R4) >> 96;\\n if (absTick & 0x20 != 0) price = (price * _R5) >> 96;\\n if (absTick & 0x40 != 0) price = (price * _R6) >> 96;\\n if (absTick & 0x80 != 0) price = (price * _R7) >> 96;\\n if (absTick & 0x100 != 0) price = (price * _R8) >> 96;\\n if (absTick & 0x200 != 0) price = (price * _R9) >> 96;\\n if (absTick & 0x400 != 0) price = (price * _R10) >> 96;\\n if (absTick & 0x800 != 0) price = (price * _R11) >> 96;\\n if (absTick & 0x1000 != 0) price = (price * _R12) >> 96;\\n if (absTick & 0x2000 != 0) price = (price * _R13) >> 96;\\n if (absTick & 0x4000 != 0) price = (price * _R14) >> 96;\\n if (absTick & 0x8000 != 0) price = (price * _R15) >> 96;\\n if (absTick & 0x10000 != 0) price = (price * _R16) >> 96;\\n if (absTick & 0x20000 != 0) price = (price * _R17) >> 96;\\n if (absTick & 0x40000 != 0) price = (price * _R18) >> 96;\\n }\\n if (tickValue > 0) price = 0x1000000000000000000000000000000000000000000000000 / price;\\n }\\n\\n function gt(Tick a, Tick b) internal pure returns (bool) {\\n return Tick.unwrap(a) > Tick.unwrap(b);\\n }\\n\\n function baseToQuote(Tick tick, uint256 base, bool roundingUp) internal pure returns (uint256) {\\n return Math.divide((base * tick.toPrice()), 1 << 96, roundingUp);\\n }\\n\\n function quoteToBase(Tick tick, uint256 quote, bool roundingUp) internal pure returns (uint256) {\\n // @dev quote = unit(uint64) * unitSize(uint64) < 2^96\\n // We don't need to check overflow here\\n return Math.divide(quote << 96, tick.toPrice(), roundingUp);\\n }\\n}\\n\",\"keccak256\":\"0xffbe19efd2b2e4e1eee3ed15c9363f5c45d70a6058b0b85ec9199e34de3b6b9b\",\"license\":\"GPL-2.0-or-later\"}},\"version\":1}", + "bytecode": "0x60a060405234801561000f575f80fd5b50604051611f16380380611f1683398101604081905261002e916100fe565b806001600160a01b03811661005c57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b61006581610078565b50506001600160a01b031660805261012f565b600180546001600160a01b031916905561009181610094565b50565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146100f9575f80fd5b919050565b5f806040838503121561010f575f80fd5b610118836100e3565b9150610126602084016100e3565b90509250929050565b608051611d826101945f395f818161014c015281816102ad0152818161037e015281816104460152818161052301528181610606015281816108c00152818161097101528181610a73015281816112ce0152818161135b01526113b80152611d825ff3fe6080604052600436106100bb575f3560e01c80636d70f7ae116100715780638da5cb5b1161004c5780638da5cb5b1461020b578063e30c397814610227578063f2fde38b14610244575f80fd5b80636d70f7ae146101a5578063715018a6146101e357806379ba5097146101f7575f80fd5b80633ccdbb28116100a15780633ccdbb281461011c5780633f322bc91461013b578063558a729714610186575f80fd5b806313ac61a4146100c657806315c7afb4146100e7575f80fd5b366100c257005b5f80fd5b3480156100d1575f80fd5b506100e56100e0366004611689565b610263565b005b3480156100f2575f80fd5b50610106610101366004611780565b610369565b604051610113919061183b565b60405180910390f35b348015610127575f80fd5b506100e5610136366004611854565b610b96565b348015610146575f80fd5b5061016e7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610113565b348015610191575f80fd5b506100e56101a03660046118a0565b610bb7565b3480156101b0575f80fd5b506101d36101bf3660046118d7565b60026020525f908152604090205460ff1681565b6040519015158152602001610113565b3480156101ee575f80fd5b506100e5610c1d565b348015610202575f80fd5b506100e5610c30565b348015610216575f80fd5b505f546001600160a01b031661016e565b348015610232575f80fd5b506001546001600160a01b031661016e565b34801561024f575f80fd5b506100e561025e3660046118d7565b610c79565b335f9081526002602052604090205460ff166102ab576040517f7c214f0400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639ca179983033878787876040516020016102f49594939291906118f2565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161032092919061194d565b5f604051808303815f875af115801561033b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261036291908101906119bb565b5050505050565b6060610373610cf6565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415806103b457506001600160a01b0383163014155b156103eb576040517fc0185c6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805f8480602001905181019061040291906119ed565b6040517f9b22917d0000000000000000000000000000000000000000000000000000000081526001600160c01b038416600482015290985092955090935091505f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639b22917d9060240160c060405180830381865afa158015610493573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104b79190611a7e565b90505f8060606104db84604001516001600160a01b03166001600160a01b03161590565b156105ea5760408481015190517fd9caed120000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201523060248201527f000000000000000000000000000000000000000000000000000000000000000090911680316044830181905294509063d9caed12906064015f604051808303815f87803b158015610571575f80fd5b505af1158015610583573d5f803e3d5ffd5b50505050846001600160a01b0316838a6040516105a09190611b2c565b5f6040518083038185875af1925050503d805f81146105da576040519150601f19603f3d011682016040523d82523d5f602084013e6105df565b606091505b5090925090506107bc565b60408481015190516370a0823160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528216906370a0823190602401602060405180830381865afa158015610653573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106779190611b42565b60405163095ea7b360e01b81526001600160a01b038881166004830152602482018390529195509082169063095ea7b3906044016020604051808303815f875af11580156106c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106eb9190611b59565b50856001600160a01b03168a6040516107049190611b2c565b5f604051808303815f865af19150503d805f811461073d576040519150601f19603f3d011682016040523d82523d5f602084013e610742565b606091505b5060405163095ea7b360e01b81526001600160a01b0389811660048301525f60248301529295509093509082169063095ea7b3906044016020604051808303815f875af1158015610795573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107b99190611b59565b50505b816107c5575f80fd5b5f6107dc85604001516001600160a01b0316610d75565b6107e69085611b88565b90505f6107fe865f01516001600160a01b0316610d75565b90505f806108158860a0015162ffffff1660171c90565b156108595760a088015161082f9062ffffff16855f610df6565b61083885610e76565b6108429190611b9b565b935061085283606086901b611bc2565b905061087f565b60a088015161086e9062ffffff16845f610ed8565b61087c90606086901b611bc2565b90505b828210801561093357506040517ffcc8fc9b0000000000000000000000000000000000000000000000000000000081526001600160c01b038b1660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063fcc8fc9b90602401602060405180830381865afa15801561090d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109319190611b59565b155b15610b51576040517fcdc92f2d0000000000000000000000000000000000000000000000000000000081526001600160c01b038b1660048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063cdc92f2d90602401602060405180830381865afa1580156109be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109e29190611be1565b90506109f08160020b610f2d565b82106109fc5750610b51565b5f610a108a60a0015162ffffff1660171c90565b15610a1e5750828403610a38565b60a08a0151610a359062ffffff168587035f610ed8565b90505b60208a015167ffffffffffffffff16610a56600284900b835f6111f5565b610a609190611bc2565b9050805f03610a70575050610b51565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633b9500b060405180606001604052808e81526020018660020b8152602001610ac38661123f565b67ffffffffffffffff168152506040518263ffffffff1660e01b8152600401610aec9190611c01565b60408051808303815f875af1158015610b07573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b2b9190611caa565b915050805f03610b3d57505050610b51565b610b478186611ccc565b945050505061087f565b610b5f8b896040015161128e565b610b6c8b895f015161128e565b60405180602001604052805f8152509b505050505050505050505050610b9061144a565b92915050565b610b9e61146f565b610bb26001600160a01b038416828461149b565b505050565b610bbf61146f565b6001600160a01b0382165f81815260026020908152604091829020805460ff191685151590811790915591519182527f1618a22a3b00b9ac70fd5a82f1f5cdd8cb272bd0f1b740ddf7c26ab05881dd5b910160405180910390a25050565b610c2561146f565b610c2e5f611583565b565b60015433906001600160a01b03168114610c6d5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b610c7681611583565b50565b610c8161146f565b600180546001600160a01b03831673ffffffffffffffffffffffffffffffffffffffff199091168117909155610cbe5f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45c15610d4f576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60017f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45d565b5f6001600160a01b038216610d8b575047919050565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610dcd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b909190611b42565b919050565b5f6207a11f19627fffff851601600281900b82128281610e1857825f03610e1a565b825b62ffffff1690505f610e53610e2f8389611cdf565b620f424088610e45578581830615151691040190565b808206151586151691040190565b905082610e6857610e6381611cf6565b610e6a565b805b98975050505050505050565b5f7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821115610ed4576040517f24775e0600000000000000000000000000000000000000000000000000000000815260048101839052602401610c64565b5090565b5f6207a11f19627fffff851601600281900b8212828415610ef957825f0392505b82620f4240019050610f22620f424087610f139190611cdf565b82810615158416908390040190565b979650505050505050565b5f610f37826115a9565b815f600282900b8113610f4a5781610f53565b610f5382611d2c565b62ffffff8116915060011615610f77576bfff97272373d413259a469909250610f88565b6c0100000000000000000000000092505b6002811615610fa75760606bfff2e50f5f656932ef12357c8402901c92505b6004811615610fc65760606bffe5caca7e10e4e61c3624ea8402901c92505b6008811615610fe55760606bffcb9843d60f6159c9db58838402901c92505b60108116156110045760606bff973b41fa98c081472e68968402901c92505b60208116156110235760606bff2ea16466c96a3843ec78b38402901c92505b60408116156110425760606bfe5dee046a99a2a811c461f18402901c92505b60808116156110615760606bfcbe86c7900a88aedcffc83b8402901c92505b6101008116156110815760606bf987a7253ac413176f2b074c8402901c92505b6102008116156110a15760606bf3392b0822b70005940c7a398402901c92505b6104008116156110c15760606be7159475a2c29b7443b29c7f8402901c92505b6108008116156110e15760606bd097f3bdfd2022b8845ad8f78402901c92505b6110008116156111015760606ba9f746462d870fdf8a65dc1f8402901c92505b6120008116156111215760606b70d869a156d2a1b890bb3df68402901c92505b6140008116156111415760606b31be135f97d08fd9812315058402901c92505b6180008116156111615760606b09aa508b5b7a84e1c677de548402901c92505b620100008116156111815760606a5d6af8dedb81196699c3298402901c92505b620200008116156111a0576060692216e584f5fa1ea926048402901c92505b620400008116156111bd57606067048a170391f7dc428402901c92505b5f8260020b13156111ee576111eb837801000000000000000000000000000000000000000000000000611bc2565b92505b5050919050565b5f6112376112058560020b610f2d565b61120f9085611cdf565b6bffffffffffffffffffffffff8116151584166c010000000000000000000000009091040190565b949350505050565b5f67ffffffffffffffff821115610ed457604080517f6dfcc650000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610c64565b6040517f9611cf6c0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0382811660248301525f917f000000000000000000000000000000000000000000000000000000000000000090911690639611cf6c90604401602060405180830381865afa158015611315573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113399190611b42565b61134290611cf6565b90505f811315611380576113806001600160a01b0383167f00000000000000000000000000000000000000000000000000000000000000008361149b565b6040517f6a256b290000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301527f00000000000000000000000000000000000000000000000000000000000000001690636a256b29906024016020604051808303815f875af11580156113fe573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114229190611b42565b50610bb283611439846001600160a01b0316610d75565b6001600160a01b038516919061149b565b5f7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45d565b5f546001600160a01b03163314610c2e5760405163118cdaa760e01b8152336004820152602401610c64565b5f6001600160a01b0384166114f0575f805f8085875af19050806114eb576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61157d565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f51141617169150508061157d576040517ff27f64e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6001805473ffffffffffffffffffffffffffffffffffffffff19169055610c7681611605565b6207ffff600282900b13806115ce57506115c56207ffff611d2c565b60020b8160020b125b15610c76576040517fce8ef7fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160c01b0381168114610c76575f80fd5b6001600160a01b0381168114610c76575f80fd5b5f805f806060858703121561169c575f80fd5b84356116a781611661565b935060208501356116b781611675565b9250604085013567ffffffffffffffff808211156116d3575f80fd5b818701915087601f8301126116e6575f80fd5b8135818111156116f4575f80fd5b886020828501011115611705575f80fd5b95989497505060200194505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561175157611751611714565b604052919050565b5f67ffffffffffffffff82111561177257611772611714565b50601f01601f191660200190565b5f8060408385031215611791575f80fd5b823561179c81611675565b9150602083013567ffffffffffffffff8111156117b7575f80fd5b8301601f810185136117c7575f80fd5b80356117da6117d582611759565b611728565b8181528660208385010111156117ee575f80fd5b816020840160208301375f602083830101528093505050509250929050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61184d602083018461180d565b9392505050565b5f805f60608486031215611866575f80fd5b833561187181611675565b925060208401359150604084013561188881611675565b809150509250925092565b8015158114610c76575f80fd5b5f80604083850312156118b1575f80fd5b82356118bc81611675565b915060208301356118cc81611893565b809150509250929050565b5f602082840312156118e7575f80fd5b813561184d81611675565b5f6001600160a01b0380881683526001600160c01b038716602084015280861660408401525060806060830152826080830152828460a08401375f60a0848401015260a0601f19601f85011683010190509695505050505050565b6001600160a01b0383168152604060208201525f611237604083018461180d565b5f82601f83011261197d575f80fd5b815161198b6117d582611759565b81815284602083860101111561199f575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f602082840312156119cb575f80fd5b815167ffffffffffffffff8111156119e1575f80fd5b6112378482850161196e565b5f805f8060808587031215611a00575f80fd5b8451611a0b81611675565b6020860151909450611a1c81611661565b6040860151909350611a2d81611675565b606086015190925067ffffffffffffffff811115611a49575f80fd5b611a558782880161196e565b91505092959194509250565b805162ffffff81168114610df1575f80fd5b8051610df181611675565b5f60c08284031215611a8e575f80fd5b60405160c0810167ffffffffffffffff8282108183111715611ab257611ab2611714565b8160405284519150611ac382611675565b9082526020840151908082168214611ad9575f80fd5b5060208201526040830151611aed81611675565b6040820152611afe60608401611a61565b6060820152611b0f60808401611a73565b6080820152611b2060a08401611a61565b60a08201529392505050565b5f82518060208501845e5f920191825250919050565b5f60208284031215611b52575f80fd5b5051919050565b5f60208284031215611b69575f80fd5b815161184d81611893565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610b9057610b90611b74565b8082018281125f831280158216821582161715611bba57611bba611b74565b505092915050565b5f82611bdc57634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215611bf1575f80fd5b81518060020b811461184d575f80fd5b5f61012083516001600160a01b0380825116855267ffffffffffffffff602083015116602086015280604083015116604086015262ffffff60608301511660608601528060808301511660808601525060a08101519050611c6960a085018262ffffff169052565b506020840151611c7e60c085018260020b9052565b50604084015167ffffffffffffffff1660e084015261010083018190525f818401908152602001611237565b5f8060408385031215611cbb575f80fd5b505080516020909101519092909150565b80820180821115610b9057610b90611b74565b8082028115828204841417610b9057610b90611b74565b5f7f80000000000000000000000000000000000000000000000000000000000000008203611d2657611d26611b74565b505f0390565b5f8160020b627fffff198103611d4457611d44611b74565b5f039291505056fea26469706673582212203d102bafa2cceb63221cf5fed2d181aa828f35df49d2c386bc2aab4b700b2a3064736f6c63430008190033", + "deployedBytecode": "0x6080604052600436106100bb575f3560e01c80636d70f7ae116100715780638da5cb5b1161004c5780638da5cb5b1461020b578063e30c397814610227578063f2fde38b14610244575f80fd5b80636d70f7ae146101a5578063715018a6146101e357806379ba5097146101f7575f80fd5b80633ccdbb28116100a15780633ccdbb281461011c5780633f322bc91461013b578063558a729714610186575f80fd5b806313ac61a4146100c657806315c7afb4146100e7575f80fd5b366100c257005b5f80fd5b3480156100d1575f80fd5b506100e56100e0366004611689565b610263565b005b3480156100f2575f80fd5b50610106610101366004611780565b610369565b604051610113919061183b565b60405180910390f35b348015610127575f80fd5b506100e5610136366004611854565b610b96565b348015610146575f80fd5b5061016e7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610113565b348015610191575f80fd5b506100e56101a03660046118a0565b610bb7565b3480156101b0575f80fd5b506101d36101bf3660046118d7565b60026020525f908152604090205460ff1681565b6040519015158152602001610113565b3480156101ee575f80fd5b506100e5610c1d565b348015610202575f80fd5b506100e5610c30565b348015610216575f80fd5b505f546001600160a01b031661016e565b348015610232575f80fd5b506001546001600160a01b031661016e565b34801561024f575f80fd5b506100e561025e3660046118d7565b610c79565b335f9081526002602052604090205460ff166102ab576040517f7c214f0400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639ca179983033878787876040516020016102f49594939291906118f2565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161032092919061194d565b5f604051808303815f875af115801561033b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261036291908101906119bb565b5050505050565b6060610373610cf6565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415806103b457506001600160a01b0383163014155b156103eb576040517fc0185c6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805f8480602001905181019061040291906119ed565b6040517f9b22917d0000000000000000000000000000000000000000000000000000000081526001600160c01b038416600482015290985092955090935091505f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639b22917d9060240160c060405180830381865afa158015610493573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104b79190611a7e565b90505f8060606104db84604001516001600160a01b03166001600160a01b03161590565b156105ea5760408481015190517fd9caed120000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201523060248201527f000000000000000000000000000000000000000000000000000000000000000090911680316044830181905294509063d9caed12906064015f604051808303815f87803b158015610571575f80fd5b505af1158015610583573d5f803e3d5ffd5b50505050846001600160a01b0316838a6040516105a09190611b2c565b5f6040518083038185875af1925050503d805f81146105da576040519150601f19603f3d011682016040523d82523d5f602084013e6105df565b606091505b5090925090506107bc565b60408481015190516370a0823160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528216906370a0823190602401602060405180830381865afa158015610653573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106779190611b42565b60405163095ea7b360e01b81526001600160a01b038881166004830152602482018390529195509082169063095ea7b3906044016020604051808303815f875af11580156106c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106eb9190611b59565b50856001600160a01b03168a6040516107049190611b2c565b5f604051808303815f865af19150503d805f811461073d576040519150601f19603f3d011682016040523d82523d5f602084013e610742565b606091505b5060405163095ea7b360e01b81526001600160a01b0389811660048301525f60248301529295509093509082169063095ea7b3906044016020604051808303815f875af1158015610795573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107b99190611b59565b50505b816107c5575f80fd5b5f6107dc85604001516001600160a01b0316610d75565b6107e69085611b88565b90505f6107fe865f01516001600160a01b0316610d75565b90505f806108158860a0015162ffffff1660171c90565b156108595760a088015161082f9062ffffff16855f610df6565b61083885610e76565b6108429190611b9b565b935061085283606086901b611bc2565b905061087f565b60a088015161086e9062ffffff16845f610ed8565b61087c90606086901b611bc2565b90505b828210801561093357506040517ffcc8fc9b0000000000000000000000000000000000000000000000000000000081526001600160c01b038b1660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063fcc8fc9b90602401602060405180830381865afa15801561090d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109319190611b59565b155b15610b51576040517fcdc92f2d0000000000000000000000000000000000000000000000000000000081526001600160c01b038b1660048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063cdc92f2d90602401602060405180830381865afa1580156109be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109e29190611be1565b90506109f08160020b610f2d565b82106109fc5750610b51565b5f610a108a60a0015162ffffff1660171c90565b15610a1e5750828403610a38565b60a08a0151610a359062ffffff168587035f610ed8565b90505b60208a015167ffffffffffffffff16610a56600284900b835f6111f5565b610a609190611bc2565b9050805f03610a70575050610b51565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633b9500b060405180606001604052808e81526020018660020b8152602001610ac38661123f565b67ffffffffffffffff168152506040518263ffffffff1660e01b8152600401610aec9190611c01565b60408051808303815f875af1158015610b07573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b2b9190611caa565b915050805f03610b3d57505050610b51565b610b478186611ccc565b945050505061087f565b610b5f8b896040015161128e565b610b6c8b895f015161128e565b60405180602001604052805f8152509b505050505050505050505050610b9061144a565b92915050565b610b9e61146f565b610bb26001600160a01b038416828461149b565b505050565b610bbf61146f565b6001600160a01b0382165f81815260026020908152604091829020805460ff191685151590811790915591519182527f1618a22a3b00b9ac70fd5a82f1f5cdd8cb272bd0f1b740ddf7c26ab05881dd5b910160405180910390a25050565b610c2561146f565b610c2e5f611583565b565b60015433906001600160a01b03168114610c6d5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b610c7681611583565b50565b610c8161146f565b600180546001600160a01b03831673ffffffffffffffffffffffffffffffffffffffff199091168117909155610cbe5f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45c15610d4f576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60017f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45d565b5f6001600160a01b038216610d8b575047919050565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610dcd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b909190611b42565b919050565b5f6207a11f19627fffff851601600281900b82128281610e1857825f03610e1a565b825b62ffffff1690505f610e53610e2f8389611cdf565b620f424088610e45578581830615151691040190565b808206151586151691040190565b905082610e6857610e6381611cf6565b610e6a565b805b98975050505050505050565b5f7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821115610ed4576040517f24775e0600000000000000000000000000000000000000000000000000000000815260048101839052602401610c64565b5090565b5f6207a11f19627fffff851601600281900b8212828415610ef957825f0392505b82620f4240019050610f22620f424087610f139190611cdf565b82810615158416908390040190565b979650505050505050565b5f610f37826115a9565b815f600282900b8113610f4a5781610f53565b610f5382611d2c565b62ffffff8116915060011615610f77576bfff97272373d413259a469909250610f88565b6c0100000000000000000000000092505b6002811615610fa75760606bfff2e50f5f656932ef12357c8402901c92505b6004811615610fc65760606bffe5caca7e10e4e61c3624ea8402901c92505b6008811615610fe55760606bffcb9843d60f6159c9db58838402901c92505b60108116156110045760606bff973b41fa98c081472e68968402901c92505b60208116156110235760606bff2ea16466c96a3843ec78b38402901c92505b60408116156110425760606bfe5dee046a99a2a811c461f18402901c92505b60808116156110615760606bfcbe86c7900a88aedcffc83b8402901c92505b6101008116156110815760606bf987a7253ac413176f2b074c8402901c92505b6102008116156110a15760606bf3392b0822b70005940c7a398402901c92505b6104008116156110c15760606be7159475a2c29b7443b29c7f8402901c92505b6108008116156110e15760606bd097f3bdfd2022b8845ad8f78402901c92505b6110008116156111015760606ba9f746462d870fdf8a65dc1f8402901c92505b6120008116156111215760606b70d869a156d2a1b890bb3df68402901c92505b6140008116156111415760606b31be135f97d08fd9812315058402901c92505b6180008116156111615760606b09aa508b5b7a84e1c677de548402901c92505b620100008116156111815760606a5d6af8dedb81196699c3298402901c92505b620200008116156111a0576060692216e584f5fa1ea926048402901c92505b620400008116156111bd57606067048a170391f7dc428402901c92505b5f8260020b13156111ee576111eb837801000000000000000000000000000000000000000000000000611bc2565b92505b5050919050565b5f6112376112058560020b610f2d565b61120f9085611cdf565b6bffffffffffffffffffffffff8116151584166c010000000000000000000000009091040190565b949350505050565b5f67ffffffffffffffff821115610ed457604080517f6dfcc650000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610c64565b6040517f9611cf6c0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0382811660248301525f917f000000000000000000000000000000000000000000000000000000000000000090911690639611cf6c90604401602060405180830381865afa158015611315573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113399190611b42565b61134290611cf6565b90505f811315611380576113806001600160a01b0383167f00000000000000000000000000000000000000000000000000000000000000008361149b565b6040517f6a256b290000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301527f00000000000000000000000000000000000000000000000000000000000000001690636a256b29906024016020604051808303815f875af11580156113fe573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114229190611b42565b50610bb283611439846001600160a01b0316610d75565b6001600160a01b038516919061149b565b5f7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45d565b5f546001600160a01b03163314610c2e5760405163118cdaa760e01b8152336004820152602401610c64565b5f6001600160a01b0384166114f0575f805f8085875af19050806114eb576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61157d565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f51141617169150508061157d576040517ff27f64e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6001805473ffffffffffffffffffffffffffffffffffffffff19169055610c7681611605565b6207ffff600282900b13806115ce57506115c56207ffff611d2c565b60020b8160020b125b15610c76576040517fce8ef7fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160c01b0381168114610c76575f80fd5b6001600160a01b0381168114610c76575f80fd5b5f805f806060858703121561169c575f80fd5b84356116a781611661565b935060208501356116b781611675565b9250604085013567ffffffffffffffff808211156116d3575f80fd5b818701915087601f8301126116e6575f80fd5b8135818111156116f4575f80fd5b886020828501011115611705575f80fd5b95989497505060200194505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561175157611751611714565b604052919050565b5f67ffffffffffffffff82111561177257611772611714565b50601f01601f191660200190565b5f8060408385031215611791575f80fd5b823561179c81611675565b9150602083013567ffffffffffffffff8111156117b7575f80fd5b8301601f810185136117c7575f80fd5b80356117da6117d582611759565b611728565b8181528660208385010111156117ee575f80fd5b816020840160208301375f602083830101528093505050509250929050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61184d602083018461180d565b9392505050565b5f805f60608486031215611866575f80fd5b833561187181611675565b925060208401359150604084013561188881611675565b809150509250925092565b8015158114610c76575f80fd5b5f80604083850312156118b1575f80fd5b82356118bc81611675565b915060208301356118cc81611893565b809150509250929050565b5f602082840312156118e7575f80fd5b813561184d81611675565b5f6001600160a01b0380881683526001600160c01b038716602084015280861660408401525060806060830152826080830152828460a08401375f60a0848401015260a0601f19601f85011683010190509695505050505050565b6001600160a01b0383168152604060208201525f611237604083018461180d565b5f82601f83011261197d575f80fd5b815161198b6117d582611759565b81815284602083860101111561199f575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f602082840312156119cb575f80fd5b815167ffffffffffffffff8111156119e1575f80fd5b6112378482850161196e565b5f805f8060808587031215611a00575f80fd5b8451611a0b81611675565b6020860151909450611a1c81611661565b6040860151909350611a2d81611675565b606086015190925067ffffffffffffffff811115611a49575f80fd5b611a558782880161196e565b91505092959194509250565b805162ffffff81168114610df1575f80fd5b8051610df181611675565b5f60c08284031215611a8e575f80fd5b60405160c0810167ffffffffffffffff8282108183111715611ab257611ab2611714565b8160405284519150611ac382611675565b9082526020840151908082168214611ad9575f80fd5b5060208201526040830151611aed81611675565b6040820152611afe60608401611a61565b6060820152611b0f60808401611a73565b6080820152611b2060a08401611a61565b60a08201529392505050565b5f82518060208501845e5f920191825250919050565b5f60208284031215611b52575f80fd5b5051919050565b5f60208284031215611b69575f80fd5b815161184d81611893565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610b9057610b90611b74565b8082018281125f831280158216821582161715611bba57611bba611b74565b505092915050565b5f82611bdc57634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215611bf1575f80fd5b81518060020b811461184d575f80fd5b5f61012083516001600160a01b0380825116855267ffffffffffffffff602083015116602086015280604083015116604086015262ffffff60608301511660608601528060808301511660808601525060a08101519050611c6960a085018262ffffff169052565b506020840151611c7e60c085018260020b9052565b50604084015167ffffffffffffffff1660e084015261010083018190525f818401908152602001611237565b5f8060408385031215611cbb575f80fd5b505080516020909101519092909150565b80820180821115610b9057610b90611b74565b8082028115828204841417610b9057610b90611b74565b5f7f80000000000000000000000000000000000000000000000000000000000000008203611d2657611d26611b74565b505f0390565b5f8160020b627fffff198103611d4457611d44611b74565b5f039291505056fea26469706673582212203d102bafa2cceb63221cf5fed2d181aa828f35df49d2c386bc2aab4b700b2a3064736f6c63430008190033", + "devdoc": { + "errors": { + "OwnableInvalidOwner(address)": [ + { + "details": "The owner is not a valid owner account. (eg. `address(0)`)" + } + ], + "OwnableUnauthorizedAccount(address)": [ + { + "details": "The caller account is not authorized to perform an operation." + } + ], + "SafeCastOverflowedUintDowncast(uint8,uint256)": [ + { + "details": "Value doesn't fit in an uint of `bits` size." + } + ], + "SafeCastOverflowedUintToInt(uint256)": [ + { + "details": "An uint value doesn't fit in an int of `bits` size." + } + ] + }, + "kind": "dev", + "methods": { + "acceptOwnership()": { + "details": "The new owner accepts the ownership transfer." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "pendingOwner()": { + "details": "Returns the address of the pending owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "ERC20TransferFailed()": [ + { + "notice": "Thrown when an ERC20 transfer fails" + } + ], + "NativeTransferFailed()": [ + { + "notice": "Thrown when a native transfer fails" + } + ] + }, + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 8, + "contract": "src/Arbitrage.sol:Arbitrage", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 156, + "contract": "src/Arbitrage.sol:Arbitrage", + "label": "_pendingOwner", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 4290, + "contract": "src/Arbitrage.sol:Arbitrage", + "label": "isOperator", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_bool)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + } + } + } +} \ No newline at end of file diff --git a/deployments/421614/solcInputs/e634729b678ce078f381c6f26baf2f0d.json b/deployments/421614/solcInputs/e634729b678ce078f381c6f26baf2f0d.json new file mode 100644 index 0000000..dfeb5fc --- /dev/null +++ b/deployments/421614/solcInputs/e634729b678ce078f381c6f26baf2f0d.json @@ -0,0 +1,174 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n /**\n * @dev The caller account is not authorized to perform an operation.\n */\n error OwnableUnauthorizedAccount(address account);\n\n /**\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\n */\n error OwnableInvalidOwner(address owner);\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n */\n constructor(address initialOwner) {\n if (initialOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(initialOwner);\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n if (owner() != _msgSender()) {\n revert OwnableUnauthorizedAccount(_msgSender());\n }\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n if (newOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.20;\n\nimport {Ownable} from \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This extension of the {Ownable} contract includes a two-step mechanism to transfer\n * ownership, where the new owner must call {acceptOwnership} in order to replace the\n * old one. This can help prevent common mistakes, such as transfers of ownership to\n * incorrect accounts, or to contracts that are unable to interact with the\n * permission system.\n *\n * The initial owner is specified at deployment time in the constructor for `Ownable`. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n if (pendingOwner() != sender) {\n revert OwnableUnauthorizedAccount(sender);\n }\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev ERC-1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1363.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1363.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n /*\n * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n * 0xb0202a11 ===\n * bytes4(keccak256('transferAndCall(address,uint256)')) ^\n * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n * bytes4(keccak256('approveAndCall(address,uint256)')) ^\n * bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n */\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`\n * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n * @param to The address which you want to transfer to.\n * @param value The amount of tokens to be transferred.\n * @return A boolean value indicating whether the operation succeeded unless throwing.\n */\n function transferAndCall(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`\n * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n * @param to The address which you want to transfer to.\n * @param value The amount of tokens to be transferred.\n * @param data Additional data with no specified format, sent in call to `to`.\n * @return A boolean value indicating whether the operation succeeded unless throwing.\n */\n function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n * @param from The address which you want to send tokens from.\n * @param to The address which you want to transfer to.\n * @param value The amount of tokens to be transferred.\n * @return A boolean value indicating whether the operation succeeded unless throwing.\n */\n function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n * @param from The address which you want to send tokens from.\n * @param to The address which you want to transfer to.\n * @param value The amount of tokens to be transferred.\n * @param data Additional data with no specified format, sent in call to `to`.\n * @return A boolean value indicating whether the operation succeeded unless throwing.\n */\n function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n * @param spender The address which will spend the funds.\n * @param value The amount of tokens to be spent.\n * @return A boolean value indicating whether the operation succeeded unless throwing.\n */\n function approveAndCall(address spender, uint256 value) external returns (bool);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n * @param spender The address which will spend the funds.\n * @param value The amount of tokens to be spent.\n * @param data Additional data with no specified format, sent in call to `spender`.\n * @return A boolean value indicating whether the operation succeeded unless throwing.\n */\n function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n" + }, + "@openzeppelin/contracts/interfaces/IERC1967.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n */\ninterface IERC1967 {\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Emitted when the beacon is changed.\n */\n event BeaconUpgraded(address indexed beacon);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {UpgradeableBeacon} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.20;\n\nimport {Proxy} from \"../Proxy.sol\";\nimport {ERC1967Utils} from \"./ERC1967Utils.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an\n * encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\n *\n * Requirements:\n *\n * - If `data` is empty, `msg.value` must be zero.\n */\n constructor(address implementation, bytes memory _data) payable {\n ERC1967Utils.upgradeToAndCall(implementation, _data);\n }\n\n /**\n * @dev Returns the current implementation address.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using\n * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function _implementation() internal view virtual override returns (address) {\n return ERC1967Utils.getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)\n\npragma solidity ^0.8.21;\n\nimport {IBeacon} from \"../beacon/IBeacon.sol\";\nimport {IERC1967} from \"../../interfaces/IERC1967.sol\";\nimport {Address} from \"../../utils/Address.sol\";\nimport {StorageSlot} from \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots.\n */\nlibrary ERC1967Utils {\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1.\n */\n // solhint-disable-next-line private-vars-leading-underscore\n bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev The `implementation` of the proxy is invalid.\n */\n error ERC1967InvalidImplementation(address implementation);\n\n /**\n * @dev The `admin` of the proxy is invalid.\n */\n error ERC1967InvalidAdmin(address admin);\n\n /**\n * @dev The `beacon` of the proxy is invalid.\n */\n error ERC1967InvalidBeacon(address beacon);\n\n /**\n * @dev An upgrade function sees `msg.value > 0` that may be lost.\n */\n error ERC1967NonPayable();\n\n /**\n * @dev Returns the current implementation address.\n */\n function getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the ERC-1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n if (newImplementation.code.length == 0) {\n revert ERC1967InvalidImplementation(newImplementation);\n }\n StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Performs implementation upgrade with additional setup call if data is nonempty.\n * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n * to avoid stuck value in the contract.\n *\n * Emits an {IERC1967-Upgraded} event.\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) internal {\n _setImplementation(newImplementation);\n emit IERC1967.Upgraded(newImplementation);\n\n if (data.length > 0) {\n Address.functionDelegateCall(newImplementation, data);\n } else {\n _checkNonPayable();\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1.\n */\n // solhint-disable-next-line private-vars-leading-underscore\n bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Returns the current admin.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using\n * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the ERC-1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n if (newAdmin == address(0)) {\n revert ERC1967InvalidAdmin(address(0));\n }\n StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {IERC1967-AdminChanged} event.\n */\n function changeAdmin(address newAdmin) internal {\n emit IERC1967.AdminChanged(getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is the keccak-256 hash of \"eip1967.proxy.beacon\" subtracted by 1.\n */\n // solhint-disable-next-line private-vars-leading-underscore\n bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Returns the current beacon.\n */\n function getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the ERC-1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n if (newBeacon.code.length == 0) {\n revert ERC1967InvalidBeacon(newBeacon);\n }\n\n StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;\n\n address beaconImplementation = IBeacon(newBeacon).implementation();\n if (beaconImplementation.code.length == 0) {\n revert ERC1967InvalidImplementation(beaconImplementation);\n }\n }\n\n /**\n * @dev Change the beacon and trigger a setup call if data is nonempty.\n * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n * to avoid stuck value in the contract.\n *\n * Emits an {IERC1967-BeaconUpgraded} event.\n *\n * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since\n * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for\n * efficiency.\n */\n function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {\n _setBeacon(newBeacon);\n emit IERC1967.BeaconUpgraded(newBeacon);\n\n if (data.length > 0) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n } else {\n _checkNonPayable();\n }\n }\n\n /**\n * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract\n * if an upgrade doesn't perform an initialization call.\n */\n function _checkNonPayable() private {\n if (msg.value > 0) {\n revert ERC1967NonPayable();\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback\n * function and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Storage of the initializable contract.\n *\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n * when using with upgradeable contracts.\n *\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n */\n struct InitializableStorage {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n uint64 _initialized;\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool _initializing;\n }\n\n // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n /**\n * @dev The contract is already initialized.\n */\n error InvalidInitialization();\n\n /**\n * @dev The contract is not initializing.\n */\n error NotInitializing();\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint64 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n * production.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n // solhint-disable-next-line var-name-mixedcase\n InitializableStorage storage $ = _getInitializableStorage();\n\n // Cache values to avoid duplicated sloads\n bool isTopLevelCall = !$._initializing;\n uint64 initialized = $._initialized;\n\n // Allowed calls:\n // - initialSetup: the contract is not in the initializing state and no previous version was\n // initialized\n // - construction: the contract is initialized at version 1 (no reininitialization) and the\n // current contract is just being deployed\n bool initialSetup = initialized == 0 && isTopLevelCall;\n bool construction = initialized == 1 && address(this).code.length == 0;\n\n if (!initialSetup && !construction) {\n revert InvalidInitialization();\n }\n $._initialized = 1;\n if (isTopLevelCall) {\n $._initializing = true;\n }\n _;\n if (isTopLevelCall) {\n $._initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint64 version) {\n // solhint-disable-next-line var-name-mixedcase\n InitializableStorage storage $ = _getInitializableStorage();\n\n if ($._initializing || $._initialized >= version) {\n revert InvalidInitialization();\n }\n $._initialized = version;\n $._initializing = true;\n _;\n $._initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n _checkInitializing();\n _;\n }\n\n /**\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n */\n function _checkInitializing() internal view virtual {\n if (!_isInitializing()) {\n revert NotInitializing();\n }\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n // solhint-disable-next-line var-name-mixedcase\n InitializableStorage storage $ = _getInitializableStorage();\n\n if ($._initializing) {\n revert InvalidInitialization();\n }\n if ($._initialized != type(uint64).max) {\n $._initialized = type(uint64).max;\n emit Initialized(type(uint64).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint64) {\n return _getInitializableStorage()._initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _getInitializableStorage()._initializing;\n }\n\n /**\n * @dev Returns a pointer to the storage namespace.\n */\n // solhint-disable-next-line var-name-mixedcase\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n assembly {\n $.slot := INITIALIZABLE_STORAGE\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC1822Proxiable} from \"../../interfaces/draft-IERC1822.sol\";\nimport {ERC1967Utils} from \"../ERC1967/ERC1967Utils.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n */\nabstract contract UUPSUpgradeable is IERC1822Proxiable {\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n address private immutable __self = address(this);\n\n /**\n * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`\n * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,\n * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.\n * If the getter returns `\"5.0.0\"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must\n * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function\n * during an upgrade.\n */\n string public constant UPGRADE_INTERFACE_VERSION = \"5.0.0\";\n\n /**\n * @dev The call is from an unauthorized context.\n */\n error UUPSUnauthorizedCallContext();\n\n /**\n * @dev The storage `slot` is unsupported as a UUID.\n */\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC-1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC-1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n _checkProxy();\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n _checkNotDelegated();\n _;\n }\n\n /**\n * @dev Implementation of the ERC-1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual notDelegated returns (bytes32) {\n return ERC1967Utils.IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n *\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data);\n }\n\n /**\n * @dev Reverts if the execution is not performed via delegatecall or the execution\n * context is not of a proxy with an ERC-1967 compliant implementation pointing to self.\n * See {_onlyProxy}.\n */\n function _checkProxy() internal view virtual {\n if (\n address(this) == __self || // Must be called through delegatecall\n ERC1967Utils.getImplementation() != __self // Must be called through an active proxy\n ) {\n revert UUPSUnauthorizedCallContext();\n }\n }\n\n /**\n * @dev Reverts if the execution is performed via delegatecall.\n * See {notDelegated}.\n */\n function _checkNotDelegated() internal view virtual {\n if (address(this) != __self) {\n // Must not be called through delegatecall\n revert UUPSUnauthorizedCallContext();\n }\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\n\n /**\n * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.\n *\n * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value\n * is expected to be the implementation slot in ERC-1967.\n *\n * Emits an {IERC1967-Upgraded} event.\n */\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {\n revert UUPSUnsupportedProxiableUUID(slot);\n }\n ERC1967Utils.upgradeToAndCall(newImplementation, data);\n } catch {\n // The implementation is not UUPS\n revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[ERC-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC-20 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 *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n * doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n * token.safeTransferFrom(msg.sender, address(this), value);\n * ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\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 * CAUTION: See Security Considerations above.\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 v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\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 value of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the value of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens as the allowance of `spender` over the\n * 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 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\n * allowance mechanism. `value` 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 value) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\nimport {Address} from \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 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 /**\n * @dev An operation with an ERC-20 token failed.\n */\n error SafeERC20FailedOperation(address token);\n\n /**\n * @dev Indicates a failed `decreaseAllowance` request.\n */\n error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\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.encodeCall(token.transfer, (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.encodeCall(token.transferFrom, (from, to, 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 forceApprove(token, spender, oldAllowance + value);\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n * value, non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n unchecked {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < requestedDecrease) {\n revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n }\n forceApprove(token, spender, currentAllowance - requestedDecrease);\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.encodeCall(token.approve, (spender, value));\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n * targeting contracts.\n *\n * Reverts if the returned value is other than `true`.\n */\n function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n if (to.code.length == 0) {\n safeTransfer(token, to, value);\n } else if (!token.transferAndCall(to, value, data)) {\n revert SafeERC20FailedOperation(address(token));\n }\n }\n\n /**\n * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n * targeting contracts.\n *\n * Reverts if the returned value is other than `true`.\n */\n function transferFromAndCallRelaxed(\n IERC1363 token,\n address from,\n address to,\n uint256 value,\n bytes memory data\n ) internal {\n if (to.code.length == 0) {\n safeTransferFrom(token, from, to, value);\n } else if (!token.transferFromAndCall(from, to, value, data)) {\n revert SafeERC20FailedOperation(address(token));\n }\n }\n\n /**\n * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n * targeting contracts.\n *\n * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n * once without retrying, and relies on the returned value to be true.\n *\n * Reverts if the returned value is other than `true`.\n */\n function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n if (to.code.length == 0) {\n forceApprove(token, to, value);\n } else if (!token.approveAndCall(to, value, data)) {\n revert SafeERC20FailedOperation(address(token));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param 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 {_callOptionalReturnBool} that reverts if call fails to meet the requirements.\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n uint256 returnSize;\n uint256 returnValue;\n assembly (\"memory-safe\") {\n let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n // bubble errors\n if iszero(success) {\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize())\n revert(ptr, returndatasize())\n }\n returnSize := returndatasize()\n returnValue := mload(0)\n }\n\n if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {\n revert SafeERC20FailedOperation(address(token));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param 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 silently catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly (\"memory-safe\") {\n success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0)\n }\n return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC721} from \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC-721 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\n * 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 ERC-721 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\n * {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\n * 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 ERC-721\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 address zero.\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/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\nimport {Errors} from \"./Errors.sol\";\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev There's no code at `target` (it is not a contract).\n */\n error AddressEmptyCode(address target);\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.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n if (address(this).balance < amount) {\n revert Errors.InsufficientBalance(address(this).balance, amount);\n }\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n if (!success) {\n revert Errors.FailedCall();\n }\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 or custom error, it is bubbled\n * up by this function (like regular Solidity function calls). However, if\n * the call reverted with no returned reason, this function reverts with a\n * {Errors.FailedCall} error.\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 function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0);\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 function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n if (address(this).balance < value) {\n revert Errors.InsufficientBalance(address(this).balance, value);\n }\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case\n * of an unsuccessful call.\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata\n ) internal view returns (bytes memory) {\n if (!success) {\n _revert(returndata);\n } else {\n // only check if target is a contract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n if (returndata.length == 0 && target.code.length == 0) {\n revert AddressEmptyCode(target);\n }\n return returndata;\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n * revert reason or with a default {Errors.FailedCall} error.\n */\n function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n if (!success) {\n _revert(returndata);\n } else {\n return returndata;\n }\n }\n\n /**\n * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.\n */\n function _revert(bytes memory returndata) 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 Errors.FailedCall();\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of common custom errors used in multiple contracts\n *\n * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.\n * It is recommended to avoid relying on the error API for critical functionality.\n */\nlibrary Errors {\n /**\n * @dev The ETH balance of the account is not enough to perform the operation.\n */\n error InsufficientBalance(uint256 balance, uint256 needed);\n\n /**\n * @dev A call to an address target failed. The target may have reverted.\n */\n error FailedCall();\n\n /**\n * @dev The deployment failed.\n */\n error FailedDeployment();\n\n /**\n * @dev A necessary precompile is missing.\n */\n error MissingPrecompile(address);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\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[ERC 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" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n /**\n * @dev Value doesn't fit in an uint of `bits` size.\n */\n error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n /**\n * @dev An int value doesn't fit in an uint of `bits` size.\n */\n error SafeCastOverflowedIntToUint(int256 value);\n\n /**\n * @dev Value doesn't fit in an int of `bits` size.\n */\n error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n /**\n * @dev An uint value doesn't fit in an int of `bits` size.\n */\n error SafeCastOverflowedUintToInt(uint256 value);\n\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n if (value > type(uint248).max) {\n revert SafeCastOverflowedUintDowncast(248, value);\n }\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n if (value > type(uint240).max) {\n revert SafeCastOverflowedUintDowncast(240, value);\n }\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n if (value > type(uint232).max) {\n revert SafeCastOverflowedUintDowncast(232, value);\n }\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n if (value > type(uint224).max) {\n revert SafeCastOverflowedUintDowncast(224, value);\n }\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n if (value > type(uint216).max) {\n revert SafeCastOverflowedUintDowncast(216, value);\n }\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n if (value > type(uint208).max) {\n revert SafeCastOverflowedUintDowncast(208, value);\n }\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n if (value > type(uint200).max) {\n revert SafeCastOverflowedUintDowncast(200, value);\n }\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n if (value > type(uint192).max) {\n revert SafeCastOverflowedUintDowncast(192, value);\n }\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n if (value > type(uint184).max) {\n revert SafeCastOverflowedUintDowncast(184, value);\n }\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n if (value > type(uint176).max) {\n revert SafeCastOverflowedUintDowncast(176, value);\n }\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n if (value > type(uint168).max) {\n revert SafeCastOverflowedUintDowncast(168, value);\n }\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n if (value > type(uint160).max) {\n revert SafeCastOverflowedUintDowncast(160, value);\n }\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n if (value > type(uint152).max) {\n revert SafeCastOverflowedUintDowncast(152, value);\n }\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n if (value > type(uint144).max) {\n revert SafeCastOverflowedUintDowncast(144, value);\n }\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n if (value > type(uint136).max) {\n revert SafeCastOverflowedUintDowncast(136, value);\n }\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n if (value > type(uint128).max) {\n revert SafeCastOverflowedUintDowncast(128, value);\n }\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n if (value > type(uint120).max) {\n revert SafeCastOverflowedUintDowncast(120, value);\n }\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n if (value > type(uint112).max) {\n revert SafeCastOverflowedUintDowncast(112, value);\n }\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n if (value > type(uint104).max) {\n revert SafeCastOverflowedUintDowncast(104, value);\n }\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n if (value > type(uint96).max) {\n revert SafeCastOverflowedUintDowncast(96, value);\n }\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n if (value > type(uint88).max) {\n revert SafeCastOverflowedUintDowncast(88, value);\n }\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n if (value > type(uint80).max) {\n revert SafeCastOverflowedUintDowncast(80, value);\n }\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n if (value > type(uint72).max) {\n revert SafeCastOverflowedUintDowncast(72, value);\n }\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n if (value > type(uint64).max) {\n revert SafeCastOverflowedUintDowncast(64, value);\n }\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n if (value > type(uint56).max) {\n revert SafeCastOverflowedUintDowncast(56, value);\n }\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n if (value > type(uint48).max) {\n revert SafeCastOverflowedUintDowncast(48, value);\n }\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n if (value > type(uint40).max) {\n revert SafeCastOverflowedUintDowncast(40, value);\n }\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n if (value > type(uint32).max) {\n revert SafeCastOverflowedUintDowncast(32, value);\n }\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n if (value > type(uint24).max) {\n revert SafeCastOverflowedUintDowncast(24, value);\n }\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n if (value > type(uint16).max) {\n revert SafeCastOverflowedUintDowncast(16, value);\n }\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n if (value > type(uint8).max) {\n revert SafeCastOverflowedUintDowncast(8, value);\n }\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n if (value < 0) {\n revert SafeCastOverflowedIntToUint(value);\n }\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(248, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(240, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(232, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(224, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(216, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(208, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(200, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(192, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(184, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(176, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(168, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(160, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(152, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(144, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(136, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(128, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(120, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(112, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(104, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(96, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(88, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(80, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(72, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(64, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(56, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(48, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(40, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(32, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(24, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(16, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(8, value);\n }\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n if (value > uint256(type(int256).max)) {\n revert SafeCastOverflowedUintToInt(value);\n }\n return int256(value);\n }\n\n /**\n * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n */\n function toUint(bool b) internal pure returns (uint256 u) {\n /// @solidity memory-safe-assembly\n assembly {\n u := iszero(iszero(b))\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.24;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(newImplementation.code.length > 0);\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * Since version 5.1, this library also support writing and reading value types to and from transient storage.\n *\n * * Example using transient storage:\n * ```solidity\n * contract Lock {\n * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n * bytes32 internal constant _LOCK_SLOT = 0xf4678858b2b588224636b8522b729e7722d32fc491da849ed75b3fdf3c84f542;\n *\n * modifier locked() {\n * require(!_LOCK_SLOT.asBoolean().tload());\n *\n * _LOCK_SLOT.asBoolean().tstore(true);\n * _;\n * _LOCK_SLOT.asBoolean().tstore(false);\n * }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n struct Int256Slot {\n int256 value;\n }\n\n struct StringSlot {\n string value;\n }\n\n struct BytesSlot {\n bytes value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Int256Slot` with member `value` located at `slot`.\n */\n function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\n */\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n */\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n */\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n */\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev UDVT that represent a slot holding a address.\n */\n type AddressSlotType is bytes32;\n\n /**\n * @dev Cast an arbitrary slot to a AddressSlotType.\n */\n function asAddress(bytes32 slot) internal pure returns (AddressSlotType) {\n return AddressSlotType.wrap(slot);\n }\n\n /**\n * @dev UDVT that represent a slot holding a bool.\n */\n type BooleanSlotType is bytes32;\n\n /**\n * @dev Cast an arbitrary slot to a BooleanSlotType.\n */\n function asBoolean(bytes32 slot) internal pure returns (BooleanSlotType) {\n return BooleanSlotType.wrap(slot);\n }\n\n /**\n * @dev UDVT that represent a slot holding a bytes32.\n */\n type Bytes32SlotType is bytes32;\n\n /**\n * @dev Cast an arbitrary slot to a Bytes32SlotType.\n */\n function asBytes32(bytes32 slot) internal pure returns (Bytes32SlotType) {\n return Bytes32SlotType.wrap(slot);\n }\n\n /**\n * @dev UDVT that represent a slot holding a uint256.\n */\n type Uint256SlotType is bytes32;\n\n /**\n * @dev Cast an arbitrary slot to a Uint256SlotType.\n */\n function asUint256(bytes32 slot) internal pure returns (Uint256SlotType) {\n return Uint256SlotType.wrap(slot);\n }\n\n /**\n * @dev UDVT that represent a slot holding a int256.\n */\n type Int256SlotType is bytes32;\n\n /**\n * @dev Cast an arbitrary slot to a Int256SlotType.\n */\n function asInt256(bytes32 slot) internal pure returns (Int256SlotType) {\n return Int256SlotType.wrap(slot);\n }\n\n /**\n * @dev Load the value held at location `slot` in transient storage.\n */\n function tload(AddressSlotType slot) internal view returns (address value) {\n /// @solidity memory-safe-assembly\n assembly {\n value := tload(slot)\n }\n }\n\n /**\n * @dev Store `value` at location `slot` in transient storage.\n */\n function tstore(AddressSlotType slot, address value) internal {\n /// @solidity memory-safe-assembly\n assembly {\n tstore(slot, value)\n }\n }\n\n /**\n * @dev Load the value held at location `slot` in transient storage.\n */\n function tload(BooleanSlotType slot) internal view returns (bool value) {\n /// @solidity memory-safe-assembly\n assembly {\n value := tload(slot)\n }\n }\n\n /**\n * @dev Store `value` at location `slot` in transient storage.\n */\n function tstore(BooleanSlotType slot, bool value) internal {\n /// @solidity memory-safe-assembly\n assembly {\n tstore(slot, value)\n }\n }\n\n /**\n * @dev Load the value held at location `slot` in transient storage.\n */\n function tload(Bytes32SlotType slot) internal view returns (bytes32 value) {\n /// @solidity memory-safe-assembly\n assembly {\n value := tload(slot)\n }\n }\n\n /**\n * @dev Store `value` at location `slot` in transient storage.\n */\n function tstore(Bytes32SlotType slot, bytes32 value) internal {\n /// @solidity memory-safe-assembly\n assembly {\n tstore(slot, value)\n }\n }\n\n /**\n * @dev Load the value held at location `slot` in transient storage.\n */\n function tload(Uint256SlotType slot) internal view returns (uint256 value) {\n /// @solidity memory-safe-assembly\n assembly {\n value := tload(slot)\n }\n }\n\n /**\n * @dev Store `value` at location `slot` in transient storage.\n */\n function tstore(Uint256SlotType slot, uint256 value) internal {\n /// @solidity memory-safe-assembly\n assembly {\n tstore(slot, value)\n }\n }\n\n /**\n * @dev Load the value held at location `slot` in transient storage.\n */\n function tload(Int256SlotType slot) internal view returns (int256 value) {\n /// @solidity memory-safe-assembly\n assembly {\n value := tload(slot)\n }\n }\n\n /**\n * @dev Store `value` at location `slot` in transient storage.\n */\n function tstore(Int256SlotType slot, int256 value) internal {\n /// @solidity memory-safe-assembly\n assembly {\n tstore(slot, value)\n }\n }\n}\n" + }, + "src/Arbitrage.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {Ownable, Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\nimport {ILocker} from \"v2-core/interfaces/ILocker.sol\";\nimport {IHooks} from \"v2-core/interfaces/IHooks.sol\";\nimport {BookId, BookIdLibrary} from \"v2-core/libraries/BookId.sol\";\nimport {Currency, CurrencyLibrary} from \"v2-core/libraries/Currency.sol\";\nimport {FeePolicy, FeePolicyLibrary} from \"v2-core/libraries/FeePolicy.sol\";\nimport {Tick, TickLibrary} from \"v2-core/libraries/Tick.sol\";\nimport {ReentrancyGuard} from \"./libraries/ReentrancyGuard.sol\";\nimport {IArbitrage} from \"./interfaces/IArbitrage.sol\";\n\ncontract Arbitrage is IArbitrage, Ownable2Step, ILocker, ReentrancyGuard {\n using TickLibrary for Tick;\n using SafeCast for uint256;\n using CurrencyLibrary for Currency;\n using FeePolicyLibrary for FeePolicy;\n\n IBookManager public immutable bookManager;\n\n mapping(address => bool) public isOperator;\n\n modifier onlyOperator() {\n if (!isOperator[msg.sender]) revert NotOperator();\n _;\n }\n\n constructor(address bookManager_, address initialOwner_) Ownable(initialOwner_) {\n bookManager = IBookManager(bookManager_);\n }\n\n function setOperator(address operator, bool status) external onlyOwner {\n isOperator[operator] = status;\n emit SetOperator(operator, status);\n }\n\n function lockAcquired(address sender, bytes memory data) external nonReentrant returns (bytes memory) {\n if (msg.sender != address(bookManager) || sender != address(this)) revert InvalidAccess();\n address user;\n BookId id;\n address router;\n (user, id, router, data) = abi.decode(data, (address, BookId, address, bytes));\n\n IBookManager.BookKey memory key = bookManager.getBookKey(id);\n uint256 max;\n bool success;\n bytes memory returnData;\n if (key.quote.isNative()) {\n max = address(bookManager).balance;\n bookManager.withdraw(key.quote, address(this), max);\n (success, returnData) = router.call{value: max}(data);\n } else {\n IERC20 quote = IERC20(Currency.unwrap(key.quote));\n max = quote.balanceOf(address(bookManager));\n quote.approve(router, max);\n (success, returnData) = router.call(data);\n quote.approve(router, 0);\n }\n if (!success) revert();\n\n uint256 quoteAmount = max - key.quote.balanceOfSelf();\n uint256 baseAmount = key.base.balanceOfSelf();\n uint256 spentBaseAmount;\n uint256 price;\n if (key.takerPolicy.usesQuote()) {\n quoteAmount = uint256(quoteAmount.toInt256() + key.takerPolicy.calculateFee(quoteAmount, false));\n price = (quoteAmount << 96) / baseAmount;\n } else {\n price = (quoteAmount << 96) / key.takerPolicy.calculateOriginalAmount(baseAmount, false);\n }\n\n while (spentBaseAmount < baseAmount && !bookManager.isEmpty(id)) {\n Tick tick = bookManager.getHighest(id);\n if (price >= tick.toPrice()) break; // Did not consider fees.\n uint256 maxAmount;\n unchecked {\n if (key.takerPolicy.usesQuote()) {\n maxAmount = baseAmount - spentBaseAmount;\n } else {\n maxAmount = key.takerPolicy.calculateOriginalAmount(baseAmount - spentBaseAmount, false);\n }\n }\n maxAmount = tick.baseToQuote(maxAmount, false) / key.unitSize;\n if (maxAmount == 0) break;\n (, uint256 amount) =\n bookManager.take(IBookManager.TakeParams({key: key, tick: tick, maxUnit: maxAmount.toUint64()}), \"\");\n if (amount == 0) break;\n spentBaseAmount += amount;\n }\n\n _settleCurrency(user, key.quote);\n _settleCurrency(user, key.base);\n\n return \"\";\n }\n\n function arbitrage(BookId id, address router, bytes calldata data) external onlyOperator {\n bookManager.lock(address(this), abi.encode(msg.sender, id, router, data));\n }\n\n function _settleCurrency(address user, Currency currency) internal {\n int256 currencyDelta = -bookManager.getCurrencyDelta(address(this), currency);\n if (currencyDelta > 0) {\n currency.transfer(address(bookManager), uint256(currencyDelta));\n }\n bookManager.settle(currency);\n currency.transfer(user, currency.balanceOfSelf());\n }\n\n function withdrawToken(Currency currency, uint256 amount, address recipient) external onlyOwner {\n currency.transfer(recipient, amount);\n }\n\n receive() external payable {}\n}\n" + }, + "src/BookViewer.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol\";\nimport {ERC1967Proxy} from \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\"; // To generate artifacts\nimport {Ownable, Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {Initializable} from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\nimport {SignificantBit} from \"v2-core/libraries/SignificantBit.sol\";\nimport {Math} from \"v2-core/libraries/Math.sol\";\nimport {Lockers} from \"v2-core/libraries/Lockers.sol\";\nimport {BookId} from \"v2-core/libraries/BookId.sol\";\nimport {Tick, TickLibrary} from \"v2-core/libraries/Tick.sol\";\nimport {FeePolicy, FeePolicyLibrary} from \"v2-core/libraries/FeePolicy.sol\";\n\nimport {IBookViewer} from \"./interfaces/IBookViewer.sol\";\nimport {IController} from \"./interfaces/IController.sol\";\n\ncontract BookViewer is IBookViewer, UUPSUpgradeable, Ownable2Step, Initializable {\n using SafeCast for *;\n using TickLibrary for *;\n using Math for uint256;\n using SignificantBit for uint256;\n using FeePolicyLibrary for FeePolicy;\n\n IBookManager public immutable bookManager;\n\n constructor(IBookManager bookManager_) Ownable(msg.sender) {\n bookManager = bookManager_;\n }\n\n function __BookViewer_init(address owner) external initializer {\n _transferOwnership(owner);\n }\n\n function _authorizeUpgrade(address) internal override onlyOwner {}\n\n function getLiquidity(BookId id, Tick tick, uint256 n) external view returns (Liquidity[] memory liquidity) {\n liquidity = new Liquidity[](n);\n if (bookManager.getDepth(id, tick) == 0) tick = bookManager.maxLessThan(id, tick);\n uint256 i;\n while (i < n) {\n if (Tick.unwrap(tick) == type(int24).min) break;\n liquidity[i] = Liquidity({tick: tick, depth: bookManager.getDepth(id, tick)});\n tick = bookManager.maxLessThan(id, tick);\n unchecked {\n ++i;\n }\n }\n assembly {\n mstore(liquidity, i)\n }\n }\n\n function getExpectedInput(IController.TakeOrderParams memory params)\n external\n view\n returns (uint256 takenQuoteAmount, uint256 spentBaseAmount)\n {\n IBookManager.BookKey memory key = bookManager.getBookKey(params.id);\n\n if (bookManager.isEmpty(params.id)) return (0, 0);\n\n Tick tick = bookManager.getHighest(params.id);\n\n while (Tick.unwrap(tick) > type(int24).min) {\n unchecked {\n if (params.limitPrice > tick.toPrice()) break;\n uint256 maxAmount;\n if (key.takerPolicy.usesQuote()) {\n maxAmount = key.takerPolicy.calculateOriginalAmount(params.quoteAmount - takenQuoteAmount, true);\n } else {\n maxAmount = params.quoteAmount - takenQuoteAmount;\n }\n maxAmount = maxAmount.divide(key.unitSize, true);\n\n if (maxAmount == 0) break;\n uint256 currentDepth = bookManager.getDepth(params.id, tick);\n uint256 quoteAmount = (currentDepth > maxAmount ? maxAmount : currentDepth) * key.unitSize;\n uint256 baseAmount = tick.quoteToBase(quoteAmount, true);\n if (key.takerPolicy.usesQuote()) {\n quoteAmount = uint256(int256(quoteAmount) - key.takerPolicy.calculateFee(quoteAmount, false));\n } else {\n baseAmount = uint256(baseAmount.toInt256() + key.takerPolicy.calculateFee(baseAmount, false));\n }\n if (quoteAmount == 0) break;\n\n takenQuoteAmount += quoteAmount;\n spentBaseAmount += baseAmount;\n if (params.quoteAmount <= takenQuoteAmount) break;\n tick = bookManager.maxLessThan(params.id, tick);\n }\n }\n }\n\n function getExpectedOutput(IController.SpendOrderParams memory params)\n external\n view\n returns (uint256 takenQuoteAmount, uint256 spentBaseAmount)\n {\n IBookManager.BookKey memory key = bookManager.getBookKey(params.id);\n\n if (bookManager.isEmpty(params.id)) return (0, 0);\n\n Tick tick = bookManager.getHighest(params.id);\n\n unchecked {\n while (spentBaseAmount <= params.baseAmount && Tick.unwrap(tick) > type(int24).min) {\n if (params.limitPrice > tick.toPrice()) break;\n uint256 maxAmount;\n if (key.takerPolicy.usesQuote()) {\n maxAmount = params.baseAmount - spentBaseAmount;\n } else {\n maxAmount = key.takerPolicy.calculateOriginalAmount(params.baseAmount - spentBaseAmount, false);\n }\n maxAmount = tick.baseToQuote(maxAmount, false) / key.unitSize;\n\n if (maxAmount == 0) break;\n uint256 currentDepth = bookManager.getDepth(params.id, tick);\n uint256 quoteAmount = (currentDepth > maxAmount ? maxAmount : currentDepth) * key.unitSize;\n uint256 baseAmount = tick.quoteToBase(quoteAmount, true);\n if (key.takerPolicy.usesQuote()) {\n quoteAmount = uint256(int256(quoteAmount) - key.takerPolicy.calculateFee(quoteAmount, false));\n } else {\n baseAmount = uint256(baseAmount.toInt256() + key.takerPolicy.calculateFee(baseAmount, false));\n }\n if (baseAmount == 0) break;\n\n takenQuoteAmount += quoteAmount;\n spentBaseAmount += baseAmount;\n tick = bookManager.maxLessThan(params.id, tick);\n }\n }\n }\n}\n" + }, + "src/Controller.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.0;\n\nimport {IERC20Permit} from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {ILocker} from \"v2-core/interfaces/ILocker.sol\";\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\nimport {IERC721Permit} from \"v2-core/interfaces/IERC721Permit.sol\";\nimport {Math} from \"v2-core/libraries/Math.sol\";\nimport {BookId, BookIdLibrary} from \"v2-core/libraries/BookId.sol\";\nimport {OrderId, OrderIdLibrary} from \"v2-core/libraries/OrderId.sol\";\nimport {Currency, CurrencyLibrary} from \"v2-core/libraries/Currency.sol\";\nimport {FeePolicy, FeePolicyLibrary} from \"v2-core/libraries/FeePolicy.sol\";\nimport {Tick, TickLibrary} from \"v2-core/libraries/Tick.sol\";\nimport {OrderId, OrderIdLibrary} from \"v2-core/libraries/OrderId.sol\";\n\nimport {IController} from \"./interfaces/IController.sol\";\nimport {ReentrancyGuard} from \"./libraries/ReentrancyGuard.sol\";\n\ncontract Controller is IController, ILocker, ReentrancyGuard {\n using TickLibrary for *;\n using OrderIdLibrary for OrderId;\n using BookIdLibrary for IBookManager.BookKey;\n using SafeERC20 for IERC20;\n using SafeCast for uint256;\n using Math for uint256;\n using CurrencyLibrary for Currency;\n using FeePolicyLibrary for FeePolicy;\n\n IBookManager public immutable bookManager;\n\n constructor(address bookManager_) {\n bookManager = IBookManager(bookManager_);\n }\n\n modifier checkDeadline(uint64 deadline) {\n if (block.timestamp > deadline) revert Deadline();\n _;\n }\n\n modifier permitERC20(ERC20PermitParams[] calldata permitParamsList) {\n _permitERC20(permitParamsList);\n _;\n }\n\n function getDepth(BookId id, Tick tick) external view returns (uint256) {\n return uint256(bookManager.getDepth(id, tick)) * bookManager.getBookKey(id).unitSize;\n }\n\n function getHighestPrice(BookId id) external view returns (uint256) {\n return bookManager.getHighest(id).toPrice();\n }\n\n function getOrder(OrderId orderId)\n external\n view\n returns (address provider, uint256 price, uint256 openAmount, uint256 claimableAmount)\n {\n (BookId bookId, Tick tick,) = orderId.decode();\n IBookManager.BookKey memory key = bookManager.getBookKey(bookId);\n uint256 unitSize = key.unitSize;\n price = tick.toPrice();\n IBookManager.OrderInfo memory orderInfo = bookManager.getOrder(orderId);\n provider = orderInfo.provider;\n openAmount = unitSize * orderInfo.open;\n FeePolicy makerPolicy = key.makerPolicy;\n claimableAmount = tick.quoteToBase(unitSize * orderInfo.claimable, false);\n if (!makerPolicy.usesQuote()) {\n int256 fee = makerPolicy.calculateFee(claimableAmount, false);\n claimableAmount = fee > 0 ? claimableAmount - uint256(fee) : claimableAmount + uint256(-fee);\n }\n }\n\n function fromPrice(uint256 price) external pure returns (Tick) {\n return price.fromPrice();\n }\n\n function toPrice(Tick tick) external pure returns (uint256) {\n return tick.toPrice();\n }\n\n function lockAcquired(address sender, bytes memory data) external nonReentrant returns (bytes memory returnData) {\n if (msg.sender != address(bookManager) || sender != address(this)) revert InvalidAccess();\n (address user, Action[] memory actionList, bytes[] memory orderParamsList, address[] memory tokensToSettle) =\n abi.decode(data, (address, Action[], bytes[], address[]));\n\n uint256 length = actionList.length;\n OrderId[] memory ids = new OrderId[](length);\n uint256 orderIdIndex;\n\n for (uint256 i = 0; i < length; ++i) {\n Action action = actionList[i];\n if (action == Action.OPEN) {\n _open(abi.decode(orderParamsList[i], (OpenBookParams)));\n } else if (action == Action.MAKE) {\n OrderId id = _make(abi.decode(orderParamsList[i], (MakeOrderParams)));\n if (OrderId.unwrap(id) != 0) {\n bookManager.transferFrom(address(this), user, OrderId.unwrap(id));\n ids[orderIdIndex++] = id;\n }\n } else if (action == Action.LIMIT) {\n OrderId id = _limit(abi.decode(orderParamsList[i], (LimitOrderParams)));\n if (OrderId.unwrap(id) != 0) {\n bookManager.transferFrom(address(this), user, OrderId.unwrap(id));\n ids[orderIdIndex++] = id;\n }\n } else if (action == Action.TAKE) {\n _take(abi.decode(orderParamsList[i], (TakeOrderParams)));\n } else if (action == Action.SPEND) {\n _spend(abi.decode(orderParamsList[i], (SpendOrderParams)));\n } else if (action == Action.CLAIM) {\n ClaimOrderParams memory claimOrderParams = abi.decode(orderParamsList[i], (ClaimOrderParams));\n uint256 orderId = OrderId.unwrap(claimOrderParams.id);\n bookManager.checkAuthorized(bookManager.ownerOf(orderId), user, orderId);\n _claim(claimOrderParams);\n } else if (action == Action.CANCEL) {\n CancelOrderParams memory cancelOrderParams = abi.decode(orderParamsList[i], (CancelOrderParams));\n uint256 orderId = OrderId.unwrap(cancelOrderParams.id);\n bookManager.checkAuthorized(bookManager.ownerOf(orderId), user, orderId);\n _cancel(cancelOrderParams);\n } else {\n revert InvalidAction();\n }\n }\n\n _settleTokens(user, tokensToSettle);\n\n assembly {\n mstore(ids, orderIdIndex)\n }\n returnData = abi.encode(ids);\n }\n\n function execute(\n Action[] calldata actionList,\n bytes[] calldata paramsDataList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata erc20PermitParamsList,\n ERC721PermitParams[] calldata erc721PermitParamsList,\n uint64 deadline\n ) external payable checkDeadline(deadline) returns (OrderId[] memory ids) {\n if (actionList.length != paramsDataList.length) revert InvalidLength();\n _permitERC20(erc20PermitParamsList);\n _permitERC721(erc721PermitParamsList);\n\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bytes memory result = bookManager.lock(address(this), lockData);\n\n if (result.length != 0) {\n (ids) = abi.decode(result, (OrderId[]));\n }\n return ids;\n }\n\n function open(OpenBookParams[] calldata openBookParamsList, uint64 deadline) external checkDeadline(deadline) {\n uint256 length = openBookParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.OPEN;\n paramsDataList[i] = abi.encode(openBookParamsList[i]);\n }\n address[] memory tokensToSettle;\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bookManager.lock(address(this), lockData);\n }\n\n function limit(\n LimitOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable checkDeadline(deadline) permitERC20(permitParamsList) returns (OrderId[] memory ids) {\n uint256 length = orderParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.LIMIT;\n paramsDataList[i] = abi.encode(orderParamsList[i]);\n }\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bytes memory result = bookManager.lock(address(this), lockData);\n (ids) = abi.decode(result, (OrderId[]));\n }\n\n function make(\n MakeOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable checkDeadline(deadline) permitERC20(permitParamsList) returns (OrderId[] memory ids) {\n uint256 length = orderParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.MAKE;\n paramsDataList[i] = abi.encode(orderParamsList[i]);\n }\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bytes memory result = bookManager.lock(address(this), lockData);\n (ids) = abi.decode(result, (OrderId[]));\n }\n\n function take(\n TakeOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable checkDeadline(deadline) permitERC20(permitParamsList) {\n uint256 length = orderParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.TAKE;\n paramsDataList[i] = abi.encode(orderParamsList[i]);\n }\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bookManager.lock(address(this), lockData);\n }\n\n function spend(\n SpendOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable checkDeadline(deadline) permitERC20(permitParamsList) {\n uint256 length = orderParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.SPEND;\n paramsDataList[i] = abi.encode(orderParamsList[i]);\n }\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bookManager.lock(address(this), lockData);\n }\n\n function claim(\n ClaimOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC721PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external checkDeadline(deadline) {\n _permitERC721(permitParamsList);\n uint256 length = orderParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.CLAIM;\n paramsDataList[i] = abi.encode(orderParamsList[i]);\n }\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bookManager.lock(address(this), lockData);\n }\n\n function cancel(\n CancelOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC721PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external checkDeadline(deadline) {\n _permitERC721(permitParamsList);\n uint256 length = orderParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.CANCEL;\n paramsDataList[i] = abi.encode(orderParamsList[i]);\n }\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bookManager.lock(address(this), lockData);\n }\n\n function _open(OpenBookParams memory params) internal {\n bookManager.open(params.key, params.hookData);\n }\n\n function _make(MakeOrderParams memory params) internal returns (OrderId id) {\n IBookManager.BookKey memory key = bookManager.getBookKey(params.id);\n\n uint256 quoteAmount = params.quoteAmount;\n if (key.makerPolicy.usesQuote()) {\n quoteAmount = key.makerPolicy.calculateOriginalAmount(quoteAmount, false);\n }\n uint64 unit = (quoteAmount / key.unitSize).toUint64();\n if (unit > 0) {\n (id,) = bookManager.make(\n IBookManager.MakeParams({key: key, tick: params.tick, unit: unit, provider: address(0)}),\n params.hookData\n );\n }\n return id;\n }\n\n function _limit(LimitOrderParams memory params) internal returns (OrderId id) {\n (, uint256 spentBaseAmount) = _spend(\n SpendOrderParams({\n id: params.takeBookId,\n limitPrice: params.limitPrice,\n baseAmount: params.quoteAmount,\n minQuoteAmount: 0,\n hookData: params.takeHookData\n })\n );\n params.quoteAmount -= spentBaseAmount;\n if (params.quoteAmount > 0) {\n id = _make(\n MakeOrderParams({\n id: params.makeBookId,\n quoteAmount: params.quoteAmount,\n tick: params.tick,\n hookData: params.makeHookData\n })\n );\n }\n }\n\n function _take(TakeOrderParams memory params)\n internal\n returns (uint256 takenQuoteAmount, uint256 spentBaseAmount)\n {\n IBookManager.BookKey memory key = bookManager.getBookKey(params.id);\n\n while (params.quoteAmount > takenQuoteAmount && !bookManager.isEmpty(params.id)) {\n Tick tick = bookManager.getHighest(params.id);\n if (params.limitPrice > tick.toPrice()) break;\n uint256 maxAmount;\n unchecked {\n if (key.takerPolicy.usesQuote()) {\n maxAmount = key.takerPolicy.calculateOriginalAmount(params.quoteAmount - takenQuoteAmount, true);\n } else {\n maxAmount = params.quoteAmount - takenQuoteAmount;\n }\n }\n maxAmount = maxAmount.divide(key.unitSize, true);\n\n if (maxAmount == 0) break;\n (uint256 quoteAmount, uint256 baseAmount) = bookManager.take(\n IBookManager.TakeParams({key: key, tick: tick, maxUnit: maxAmount.toUint64()}), params.hookData\n );\n if (quoteAmount == 0) break;\n\n takenQuoteAmount += quoteAmount;\n spentBaseAmount += baseAmount;\n }\n if (params.maxBaseAmount < spentBaseAmount) revert ControllerSlippage();\n }\n\n function _spend(SpendOrderParams memory params)\n internal\n returns (uint256 takenQuoteAmount, uint256 spentBaseAmount)\n {\n IBookManager.BookKey memory key = bookManager.getBookKey(params.id);\n\n while (spentBaseAmount < params.baseAmount && !bookManager.isEmpty(params.id)) {\n Tick tick = bookManager.getHighest(params.id);\n if (params.limitPrice > tick.toPrice()) break;\n uint256 maxAmount;\n unchecked {\n if (key.takerPolicy.usesQuote()) {\n maxAmount = params.baseAmount - spentBaseAmount;\n } else {\n maxAmount = key.takerPolicy.calculateOriginalAmount(params.baseAmount - spentBaseAmount, false);\n }\n }\n maxAmount = tick.baseToQuote(maxAmount, false) / key.unitSize;\n if (maxAmount == 0) break;\n (uint256 quoteAmount, uint256 baseAmount) = bookManager.take(\n IBookManager.TakeParams({key: key, tick: tick, maxUnit: maxAmount.toUint64()}), params.hookData\n );\n if (baseAmount == 0) break;\n takenQuoteAmount += quoteAmount;\n spentBaseAmount += baseAmount;\n }\n if (params.minQuoteAmount > takenQuoteAmount) revert ControllerSlippage();\n }\n\n function _claim(ClaimOrderParams memory params) internal {\n bookManager.claim(params.id, params.hookData);\n }\n\n function _cancel(CancelOrderParams memory params) internal {\n IBookManager.BookKey memory key = bookManager.getBookKey(params.id.getBookId());\n try bookManager.cancel(\n IBookManager.CancelParams({id: params.id, toUnit: (params.leftQuoteAmount / key.unitSize).toUint64()}),\n params.hookData\n ) {} catch {}\n }\n\n function _settleTokens(address user, address[] memory tokensToSettle) internal {\n Currency native = CurrencyLibrary.NATIVE;\n int256 currencyDelta = bookManager.getCurrencyDelta(address(this), native);\n if (currencyDelta < 0) {\n native.transfer(address(bookManager), uint256(-currencyDelta));\n bookManager.settle(native);\n }\n currencyDelta = bookManager.getCurrencyDelta(address(this), native);\n if (currencyDelta > 0) {\n bookManager.withdraw(native, user, uint256(currencyDelta));\n }\n\n uint256 length = tokensToSettle.length;\n for (uint256 i = 0; i < length; ++i) {\n Currency currency = Currency.wrap(tokensToSettle[i]);\n currencyDelta = bookManager.getCurrencyDelta(address(this), currency);\n if (currencyDelta < 0) {\n IERC20(tokensToSettle[i]).safeTransferFrom(user, address(bookManager), uint256(-currencyDelta));\n bookManager.settle(currency);\n }\n currencyDelta = bookManager.getCurrencyDelta(address(this), currency);\n if (currencyDelta > 0) {\n bookManager.withdraw(Currency.wrap(tokensToSettle[i]), user, uint256(currencyDelta));\n }\n uint256 balance = IERC20(tokensToSettle[i]).balanceOf(address(this));\n if (balance > 0) {\n IERC20(tokensToSettle[i]).transfer(user, balance);\n }\n }\n if (address(this).balance > 0) native.transfer(user, address(this).balance);\n }\n\n function _permitERC20(ERC20PermitParams[] calldata permitParamsList) internal {\n for (uint256 i = 0; i < permitParamsList.length; ++i) {\n ERC20PermitParams memory permitParams = permitParamsList[i];\n if (permitParams.signature.deadline > 0) {\n try IERC20Permit(permitParams.token).permit(\n msg.sender,\n address(this),\n permitParams.permitAmount,\n permitParams.signature.deadline,\n permitParams.signature.v,\n permitParams.signature.r,\n permitParams.signature.s\n ) {} catch {}\n }\n }\n }\n\n function _permitERC721(ERC721PermitParams[] calldata permitParamsList) internal {\n for (uint256 i = 0; i < permitParamsList.length; ++i) {\n PermitSignature memory signature = permitParamsList[i].signature;\n if (signature.deadline > 0) {\n try IERC721Permit(address(bookManager)).permit(\n address(this),\n permitParamsList[i].tokenId,\n signature.deadline,\n signature.v,\n signature.r,\n signature.s\n ) {} catch {}\n }\n }\n }\n\n receive() external payable {}\n}\n" + }, + "src/interfaces/IArbitrage.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {BookId} from \"v2-core/libraries/BookId.sol\";\nimport {Currency} from \"v2-core/libraries/Currency.sol\";\n\ninterface IArbitrage {\n error InvalidAccess();\n error NotOperator();\n\n event SetOperator(address indexed operator, bool status);\n\n function setOperator(address operator, bool status) external;\n\n function arbitrage(BookId id, address router, bytes calldata data) external;\n\n function withdrawToken(Currency currency, uint256 amount, address recipient) external;\n}\n" + }, + "src/interfaces/IBookViewer.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {BookId} from \"v2-core/libraries/BookId.sol\";\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\nimport {Tick} from \"v2-core/libraries/Tick.sol\";\n\nimport {IController} from \"./IController.sol\";\n\n/**\n * @title IBookViewer\n * @notice Interface for the book viewer contract\n */\ninterface IBookViewer {\n struct Liquidity {\n Tick tick;\n uint64 depth;\n }\n\n /**\n * @notice Returns the book manager\n * @return The instance of the book manager\n */\n function bookManager() external view returns (IBookManager);\n\n /**\n * @notice Returns the liquidity for a specific book\n * @param id The id of the book\n * @param from The starting tick\n * @param n The number of ticks to return\n * @return liquidity An array of liquidity data\n */\n function getLiquidity(BookId id, Tick from, uint256 n) external view returns (Liquidity[] memory liquidity);\n\n /**\n * @notice Returns the expected input for a take order\n * @param params The parameters of the take order\n * @return takenQuoteAmount The expected taken quote amount\n * @return spentBaseAmount The expected spend base amount\n */\n function getExpectedInput(IController.TakeOrderParams memory params)\n external\n view\n returns (uint256 takenQuoteAmount, uint256 spentBaseAmount);\n\n /**\n * @notice Returns the expected output for a spend order\n * @param params The parameters of the spend order\n * @return takenQuoteAmount The expected taken quote amount\n * @return spentBaseAmount The expected spend base amount\n */\n function getExpectedOutput(IController.SpendOrderParams memory params)\n external\n view\n returns (uint256 takenQuoteAmount, uint256 spentBaseAmount);\n}\n" + }, + "src/interfaces/IController.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {OrderId} from \"v2-core/libraries/OrderId.sol\";\nimport {BookId} from \"v2-core/libraries/BookId.sol\";\nimport {Tick} from \"v2-core/libraries/Tick.sol\";\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\n\n/**\n * @title IController\n * @notice Interface for the controller contract\n */\ninterface IController {\n // Error messages\n error InvalidAccess();\n error InvalidLength();\n error Deadline();\n error ControllerSlippage();\n error InvalidAction();\n\n /**\n * @notice Enum for the different actions that can be performed\n */\n enum Action {\n OPEN,\n MAKE,\n LIMIT,\n TAKE,\n SPEND,\n CLAIM,\n CANCEL\n }\n\n /**\n * @notice Struct for the parameters of the ERC20 permit\n */\n struct ERC20PermitParams {\n address token;\n uint256 permitAmount;\n PermitSignature signature;\n }\n\n /**\n * @notice Struct for the parameters of the ERC721 permit\n */\n struct ERC721PermitParams {\n uint256 tokenId;\n PermitSignature signature;\n }\n\n /**\n * @notice Struct for the signature of the permit\n */\n struct PermitSignature {\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n /**\n * @notice Struct for the parameters of the open book action\n */\n struct OpenBookParams {\n IBookManager.BookKey key;\n bytes hookData;\n }\n\n /**\n * @notice Struct for the parameters of the make order action\n */\n struct MakeOrderParams {\n BookId id;\n Tick tick;\n uint256 quoteAmount;\n bytes hookData;\n }\n\n /**\n * @notice Struct for the parameters of the limit order action\n */\n struct LimitOrderParams {\n BookId takeBookId;\n BookId makeBookId;\n uint256 limitPrice;\n Tick tick;\n uint256 quoteAmount;\n bytes takeHookData;\n bytes makeHookData;\n }\n\n /**\n * @notice Struct for the parameters of the take order action\n */\n struct TakeOrderParams {\n BookId id;\n uint256 limitPrice;\n uint256 quoteAmount;\n uint256 maxBaseAmount;\n bytes hookData;\n }\n\n /**\n * @notice Struct for the parameters of the spend order action\n */\n struct SpendOrderParams {\n BookId id;\n uint256 limitPrice;\n uint256 baseAmount;\n uint256 minQuoteAmount;\n bytes hookData;\n }\n\n /**\n * @notice Struct for the parameters of the claim order action\n */\n struct ClaimOrderParams {\n OrderId id;\n bytes hookData;\n }\n\n /**\n * @notice Struct for the parameters of the cancel order action\n */\n struct CancelOrderParams {\n OrderId id;\n uint256 leftQuoteAmount;\n bytes hookData;\n }\n\n /**\n * @notice Returns the book manager\n * @return The instance of the book manager\n */\n function bookManager() external view returns (IBookManager);\n\n /**\n * @notice Opens a book\n * @param openBookParamsList The parameters of the open book action\n * @param deadline The deadline for the action\n */\n function open(OpenBookParams[] calldata openBookParamsList, uint64 deadline) external;\n\n /**\n * @notice Returns the depth of a book\n * @param id The id of the book\n * @param tick The tick of the book\n * @return The depth of the book in quote amount\n */\n function getDepth(BookId id, Tick tick) external view returns (uint256);\n\n /**\n * @notice Returns the highest price of a book\n * @param id The id of the book\n * @return The highest price of the book with 2**96 precision\n */\n function getHighestPrice(BookId id) external view returns (uint256);\n\n /**\n * @notice Returns the details of an order\n * @param orderId The id of the order\n * @return provider The provider of the order\n * @return price The price of the order with 2**96 precision\n * @return openAmount The open quote amount of the order\n * @return claimableAmount The claimable base amount of the order\n */\n function getOrder(OrderId orderId)\n external\n view\n returns (address provider, uint256 price, uint256 openAmount, uint256 claimableAmount);\n\n /**\n * @notice Converts a price to a tick\n * @param price The price to convert\n * @return The tick\n */\n function fromPrice(uint256 price) external pure returns (Tick);\n\n /**\n * @notice Converts a tick to a price\n * @param tick The tick to convert\n * @return The price with 2**96 precision\n */\n function toPrice(Tick tick) external pure returns (uint256);\n\n /**\n * @notice Executes a list of actions\n * @dev IMPORTANT: The caller must provide `tokensToSettle` to receive appropriate tokens after execution.\n * @param actionList The list of actions to execute\n * @param paramsDataList The parameters of the actions\n * @param tokensToSettle The tokens to settle\n * @param erc20PermitParamsList The parameters of the ERC20 permits\n * @param erc721PermitParamsList The parameters of the ERC721 permits\n * @param deadline The deadline for the actions\n * @return ids The ids of the orders\n */\n function execute(\n Action[] calldata actionList,\n bytes[] calldata paramsDataList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata erc20PermitParamsList,\n ERC721PermitParams[] calldata erc721PermitParamsList,\n uint64 deadline\n ) external payable returns (OrderId[] memory ids);\n\n /**\n * @notice Makes a list of orders\n * @dev IMPORTANT: The caller must provide `tokensToSettle` to receive appropriate tokens after execution.\n * @param orderParamsList The list of actions to make\n * @param tokensToSettle The tokens to settle\n * @param permitParamsList The parameters of the permits\n * @param deadline The deadline for the actions\n * @return ids The ids of the orders\n */\n function make(\n MakeOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable returns (OrderId[] memory ids);\n\n /**\n * @notice Takes a list of orders\n * @dev IMPORTANT: The caller must provide `tokensToSettle` to receive appropriate tokens after execution.\n * @param orderParamsList The list of actions to take\n * @param tokensToSettle The tokens to settle\n * @param permitParamsList The parameters of the permits\n * @param deadline The deadline for the actions\n */\n function take(\n TakeOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable;\n\n /**\n * @notice Spends to take a list of orders\n * @dev IMPORTANT: The caller must provide `tokensToSettle` to receive appropriate tokens after execution.\n * @param orderParamsList The list of actions to spend\n * @param tokensToSettle The tokens to settle\n * @param permitParamsList The parameters of the permits\n * @param deadline The deadline for the actions\n */\n function spend(\n SpendOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable;\n\n /**\n * @notice Claims a list of orders\n * @dev IMPORTANT: The caller must provide `tokensToSettle` to receive appropriate tokens after execution.\n * @param orderParamsList The list of actions to claim\n * @param tokensToSettle The tokens to settle\n * @param permitParamsList The parameters of the permits\n * @param deadline The deadline for the actions\n */\n function claim(\n ClaimOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC721PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external;\n\n /**\n * @notice Cancels a list of orders\n * @dev IMPORTANT: The caller must provide `tokensToSettle` to receive appropriate tokens after execution.\n * @param orderParamsList The list of actions to cancel\n * @param tokensToSettle The tokens to settle\n * @param permitParamsList The parameters of the permits\n * @param deadline The deadline for the actions\n */\n function cancel(\n CancelOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC721PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external;\n}\n" + }, + "src/interfaces/IProvider.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {Currency, CurrencyLibrary} from \"v2-core/libraries/Currency.sol\";\nimport {IProviderFactory} from \"./IProviderFactory.sol\";\n\ninterface IProvider {\n event Claim(\n address indexed broker,\n address indexed protocolTreasury,\n Currency indexed currency,\n uint256 brokerShare,\n uint256 protocolShare\n );\n\n function factory() external returns (IProviderFactory);\n\n function broker() external returns (address);\n\n function shareRatio() external returns (uint256);\n\n function claim(Currency[] calldata currencies) external;\n}\n" + }, + "src/interfaces/IProviderFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\n\ninterface IProviderFactory {\n event DeployProvider(address indexed provider, address indexed broker, uint256 shareRatio);\n\n event SetTreasury(address indexed treasury);\n\n function bookManager() external returns (IBookManager);\n\n function treasury() external returns (address);\n\n function deployProvider(address broker) external returns (address);\n\n function deployProvider(address broker, uint256 shareRatio) external returns (address);\n\n function setTreasury(address newTreasury) external;\n\n /**\n * @notice Whitelists a provider\n * @param provider The provider address\n */\n function whitelist(address provider) external;\n\n /**\n * @notice Delists a provider\n * @param provider The provider address\n */\n function delist(address provider) external;\n\n /**\n * @notice Sets the default provider\n * @param newDefaultProvider The new default provider address\n */\n function setDefaultProvider(address newDefaultProvider) external;\n\n function transferBookManagerOwnership(address newOwner) external;\n}\n" + }, + "src/libraries/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.24;\n\nabstract contract ReentrancyGuard {\n // uint256(keccak256(\"ReentrancyGuard\")) - 1\n uint256 internal constant REENTRANCY_GUARD_SLOT = 0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4;\n\n error ReentrancyGuardReentrantCall();\n\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n if (_reentrancyGuardEntered()) {\n revert ReentrancyGuardReentrantCall();\n }\n assembly {\n // Any calls to nonReentrant after this point will fail\n tstore(REENTRANCY_GUARD_SLOT, 1)\n }\n }\n\n function _nonReentrantAfter() private {\n assembly {\n tstore(REENTRANCY_GUARD_SLOT, 0)\n }\n }\n\n function _reentrancyGuardEntered() internal view returns (bool isEntered) {\n assembly {\n isEntered := tload(REENTRANCY_GUARD_SLOT)\n }\n }\n}\n" + }, + "src/Provider.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\nimport {Currency, CurrencyLibrary} from \"v2-core/libraries/Currency.sol\";\nimport {IProvider} from \"./interfaces/IProvider.sol\";\nimport {IProviderFactory} from \"./interfaces/IProviderFactory.sol\";\n\ncontract Provider is IProvider {\n using CurrencyLibrary for Currency;\n\n uint256 public constant RATE_PRECISION = 10 ** 6;\n\n IBookManager private immutable _bookManager;\n IProviderFactory public immutable factory;\n address public immutable broker;\n uint256 public immutable shareRatio;\n\n constructor(address broker_, uint256 shareRatio_) {\n factory = IProviderFactory(msg.sender);\n _bookManager = factory.bookManager();\n broker = broker_;\n shareRatio = shareRatio_;\n }\n\n function claim(Currency[] calldata currencies) external {\n address protocolTreasury = factory.treasury();\n for (uint256 i = 0; i < currencies.length; ++i) {\n Currency currency = currencies[i];\n _bookManager.collect(address(this), currency);\n uint256 balance = currency.balanceOfSelf();\n uint256 brokerShare = balance * shareRatio / RATE_PRECISION;\n uint256 protocolShare = balance - brokerShare;\n currency.transfer(broker, brokerShare);\n currency.transfer(protocolTreasury, protocolShare);\n emit Claim(broker, protocolTreasury, currency, brokerShare, protocolShare);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "src/ProviderFactory.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {Ownable2Step, Ownable} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport {IProviderFactory} from \"./interfaces/IProviderFactory.sol\";\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\nimport {Provider} from \"./Provider.sol\";\n\ncontract ProviderFactory is IProviderFactory, UUPSUpgradeable, Ownable2Step, Initializable {\n uint256 public defaultBrokerShareRatio;\n IBookManager public bookManager;\n address public treasury;\n\n constructor() Ownable(msg.sender) {}\n\n function __ProviderFactory_init(\n address owner_,\n address bookManager_,\n address treasury_,\n uint256 defaultBrokerShareRatio_\n ) public initializer {\n _transferOwnership(owner_);\n Ownable2Step(bookManager_).acceptOwnership();\n bookManager = IBookManager(bookManager_);\n treasury = treasury_;\n defaultBrokerShareRatio = defaultBrokerShareRatio_;\n }\n\n function _authorizeUpgrade(address) internal override onlyOwner {}\n\n function deployProvider(address broker) external returns (address) {\n return _deployProvider(broker, defaultBrokerShareRatio);\n }\n\n function deployProvider(address broker, uint256 shareRatio) public onlyOwner returns (address) {\n return _deployProvider(broker, shareRatio);\n }\n\n function _deployProvider(address broker, uint256 shareRatio) internal returns (address provider) {\n provider = address(new Provider(broker, shareRatio));\n bookManager.whitelist(provider);\n emit DeployProvider(provider, broker, shareRatio);\n }\n\n function setTreasury(address newTreasury) external onlyOwner {\n treasury = newTreasury;\n emit SetTreasury(newTreasury);\n }\n\n function whitelist(address provider) external onlyOwner {\n bookManager.whitelist(provider);\n }\n\n function delist(address provider) external onlyOwner {\n bookManager.delist(provider);\n }\n\n function setDefaultProvider(address newDefaultProvider) external onlyOwner {\n bookManager.setDefaultProvider(newDefaultProvider);\n }\n\n function transferBookManagerOwnership(address newOwner) external onlyOwner {\n Ownable2Step(address(bookManager)).transferOwnership(newOwner);\n }\n}\n" + }, + "v2-core/interfaces/IBookManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\n\nimport {BookId} from \"../libraries/BookId.sol\";\nimport {Currency} from \"../libraries/Currency.sol\";\nimport {OrderId} from \"../libraries/OrderId.sol\";\nimport {Tick} from \"../libraries/Tick.sol\";\nimport {FeePolicy} from \"../libraries/FeePolicy.sol\";\nimport {IERC721Permit} from \"./IERC721Permit.sol\";\nimport {IHooks} from \"./IHooks.sol\";\n\n/**\n * @title IBookManager\n * @notice The interface for the BookManager contract\n */\ninterface IBookManager is IERC721Metadata, IERC721Permit {\n error InvalidUnitSize();\n error InvalidFeePolicy();\n error InvalidProvider(address provider);\n error LockedBy(address locker, address hook);\n error CurrencyNotSettled();\n\n /**\n * @notice Event emitted when a new book is opened\n * @param id The book id\n * @param base The base currency\n * @param quote The quote currency\n * @param unitSize The unit size of the book\n * @param makerPolicy The maker fee policy\n * @param takerPolicy The taker fee policy\n * @param hooks The hooks contract\n */\n event Open(\n BookId indexed id,\n Currency indexed base,\n Currency indexed quote,\n uint64 unitSize,\n FeePolicy makerPolicy,\n FeePolicy takerPolicy,\n IHooks hooks\n );\n\n /**\n * @notice Event emitted when a new order is made\n * @param bookId The book id\n * @param user The user address\n * @param tick The order tick\n * @param orderIndex The order index\n * @param unit The order unit\n * @param provider The provider address\n */\n event Make(\n BookId indexed bookId, address indexed user, Tick tick, uint256 orderIndex, uint64 unit, address provider\n );\n\n /**\n * @notice Event emitted when an order is taken\n * @param bookId The book id\n * @param user The user address\n * @param tick The order tick\n * @param unit The order unit\n */\n event Take(BookId indexed bookId, address indexed user, Tick tick, uint64 unit);\n\n /**\n * @notice Event emitted when an order is canceled\n * @param orderId The order id\n * @param unit The canceled unit\n */\n event Cancel(OrderId indexed orderId, uint64 unit);\n\n /**\n * @notice Event emitted when an order is claimed\n * @param orderId The order id\n * @param unit The claimed unit\n */\n event Claim(OrderId indexed orderId, uint64 unit);\n\n /**\n * @notice Event emitted when a provider is whitelisted\n * @param provider The provider address\n */\n event Whitelist(address indexed provider);\n\n /**\n * @notice Event emitted when a provider is delisted\n * @param provider The provider address\n */\n event Delist(address indexed provider);\n\n /**\n * @notice Event emitted when a provider collects fees\n * @param provider The provider address\n * @param recipient The recipient address\n * @param currency The currency\n * @param amount The collected amount\n */\n event Collect(address indexed provider, address indexed recipient, Currency indexed currency, uint256 amount);\n\n /**\n * @notice Event emitted when new default provider is set\n * @param newDefaultProvider The new default provider address\n */\n event SetDefaultProvider(address indexed newDefaultProvider);\n\n /**\n * @notice This structure represents a unique identifier for a book in the BookManager.\n * @param base The base currency of the book\n * @param unitSize The unit size of the book\n * @param quote The quote currency of the book\n * @param makerPolicy The maker fee policy of the book\n * @param hooks The hooks contract of the book\n * @param takerPolicy The taker fee policy of the book\n */\n struct BookKey {\n Currency base;\n uint64 unitSize;\n Currency quote;\n FeePolicy makerPolicy;\n IHooks hooks;\n FeePolicy takerPolicy;\n }\n\n /**\n * @notice Returns the base URI\n * @return The base URI\n */\n function baseURI() external view returns (string memory);\n\n /**\n * @notice Returns the contract URI\n * @return The contract URI\n */\n function contractURI() external view returns (string memory);\n\n /**\n * @notice Returns the default provider\n * @return The default provider\n */\n function defaultProvider() external view returns (address);\n\n /**\n * @notice Returns the total reserves of a given currency\n * @param currency The currency in question\n * @return The total reserves amount\n */\n function reservesOf(Currency currency) external view returns (uint256);\n\n /**\n * @notice Checks if a provider is whitelisted\n * @param provider The address of the provider\n * @return True if the provider is whitelisted, false otherwise\n */\n function isWhitelisted(address provider) external view returns (bool);\n\n /**\n * @notice Verifies if an owner has authorized a spender for a token\n * @param owner The address of the token owner\n * @param spender The address of the spender\n * @param tokenId The token ID\n */\n function checkAuthorized(address owner, address spender, uint256 tokenId) external view;\n\n /**\n * @notice Calculates the amount owed to a provider in a given currency\n * @param provider The provider's address\n * @param currency The currency in question\n * @return The owed amount\n */\n function tokenOwed(address provider, Currency currency) external view returns (uint256);\n\n /**\n * @notice Calculates the currency balance changes for a given locker\n * @param locker The address of the locker\n * @param currency The currency in question\n * @return The net change in currency balance\n */\n function getCurrencyDelta(address locker, Currency currency) external view returns (int256);\n\n /**\n * @notice Retrieves the book key for a given book ID\n * @param id The book ID\n * @return The book key\n */\n function getBookKey(BookId id) external view returns (BookKey memory);\n\n /**\n * @notice This structure represents a current status for an order in the BookManager.\n * @param provider The provider of the order\n * @param open The open unit of the order\n * @param claimable The claimable unit of the order\n */\n struct OrderInfo {\n address provider;\n uint64 open;\n uint64 claimable;\n }\n\n /**\n * @notice Provides information about an order\n * @param id The order ID\n * @return Order information including provider, open status, and claimable unit\n */\n function getOrder(OrderId id) external view returns (OrderInfo memory);\n\n /**\n * @notice Retrieves the locker and caller addresses for a given lock\n * @param i The index of the lock\n * @return locker The locker's address\n * @return lockCaller The caller's address\n */\n function getLock(uint256 i) external view returns (address locker, address lockCaller);\n\n /**\n * @notice Provides the lock data\n * @return The lock data including necessary numeric values\n */\n function getLockData() external view returns (uint128, uint128);\n\n /**\n * @notice Returns the depth of a given book ID and tick\n * @param id The book ID\n * @param tick The tick\n * @return The depth of the tick\n */\n function getDepth(BookId id, Tick tick) external view returns (uint64);\n\n /**\n * @notice Retrieves the highest tick for a given book ID\n * @param id The book ID\n * @return tick The highest tick\n */\n function getHighest(BookId id) external view returns (Tick tick);\n\n /**\n * @notice Finds the maximum tick less than a specified tick in a book\n * @dev Returns `Tick.wrap(type(int24).min)` if the specified tick is the lowest\n * @param id The book ID\n * @param tick The specified tick\n * @return The next lower tick\n */\n function maxLessThan(BookId id, Tick tick) external view returns (Tick);\n\n /**\n * @notice Checks if a book is opened\n * @param id The book ID\n * @return True if the book is opened, false otherwise\n */\n function isOpened(BookId id) external view returns (bool);\n\n /**\n * @notice Checks if a book is empty\n * @param id The book ID\n * @return True if the book is empty, false otherwise\n */\n function isEmpty(BookId id) external view returns (bool);\n\n /**\n * @notice Encodes a BookKey into a BookId\n * @param key The BookKey to encode\n * @return The encoded BookId\n */\n function encodeBookKey(BookKey calldata key) external pure returns (BookId);\n\n /**\n * @notice Loads a value from a specific storage slot\n * @param slot The storage slot\n * @return The value in the slot\n */\n function load(bytes32 slot) external view returns (bytes32);\n\n /**\n * @notice Loads a sequence of values starting from a specific slot\n * @param startSlot The starting slot\n * @param nSlot The number of slots to load\n * @return The sequence of values\n */\n function load(bytes32 startSlot, uint256 nSlot) external view returns (bytes memory);\n\n /**\n * @notice Opens a new book\n * @param key The book key\n * @param hookData The hook data\n */\n function open(BookKey calldata key, bytes calldata hookData) external;\n\n /**\n * @notice Locks a book manager function\n * @param locker The locker address\n * @param data The lock data\n * @return The lock return data\n */\n function lock(address locker, bytes calldata data) external returns (bytes memory);\n\n /**\n * @notice This structure represents the parameters for making an order.\n * @param key The book key for the order\n * @param tick The tick for the order\n * @param unit The unit for the order. Times key.unitSize to get actual bid amount.\n * @param provider The provider for the order. The limit order service provider address to collect fees.\n */\n struct MakeParams {\n BookKey key;\n Tick tick;\n uint64 unit;\n address provider;\n }\n\n /**\n * @notice Make a limit order\n * @param params The order parameters\n * @param hookData The hook data\n * @return id The order id. Returns 0 if the order is not settled\n * @return quoteAmount The amount of quote currency to be paid\n */\n function make(MakeParams calldata params, bytes calldata hookData)\n external\n returns (OrderId id, uint256 quoteAmount);\n\n /**\n * @notice This structure represents the parameters for taking orders in the specified tick.\n * @param key The book key for the order\n * @param tick The tick for the order\n * @param maxUnit The max unit to take\n */\n struct TakeParams {\n BookKey key;\n Tick tick;\n uint64 maxUnit;\n }\n\n /**\n * @notice Take a limit order at specific tick\n * @param params The order parameters\n * @param hookData The hook data\n * @return quoteAmount The amount of quote currency to be received\n * @return baseAmount The amount of base currency to be paid\n */\n function take(TakeParams calldata params, bytes calldata hookData)\n external\n returns (uint256 quoteAmount, uint256 baseAmount);\n\n /**\n * @notice This structure represents the parameters for canceling an order.\n * @param id The order id for the order\n * @param toUnit The remaining open unit for the order after cancellation. Must not exceed the current open unit.\n */\n struct CancelParams {\n OrderId id;\n uint64 toUnit;\n }\n\n /**\n * @notice Cancel a limit order\n * @param params The order parameters\n * @param hookData The hook data\n * @return canceledAmount The amount of quote currency canceled\n */\n function cancel(CancelParams calldata params, bytes calldata hookData) external returns (uint256 canceledAmount);\n\n /**\n * @notice Claims an order\n * @param id The order ID\n * @param hookData The hook data\n * @return claimedAmount The amount claimed\n */\n function claim(OrderId id, bytes calldata hookData) external returns (uint256 claimedAmount);\n\n /**\n * @notice Collects fees from a provider\n * @param recipient The recipient address\n * @param currency The currency\n * @return The collected amount\n */\n function collect(address recipient, Currency currency) external returns (uint256);\n\n /**\n * @notice Withdraws a currency\n * @param currency The currency\n * @param to The recipient address\n * @param amount The amount\n */\n function withdraw(Currency currency, address to, uint256 amount) external;\n\n /**\n * @notice Settles a currency\n * @param currency The currency\n * @return The settled amount\n */\n function settle(Currency currency) external payable returns (uint256);\n\n /**\n * @notice Whitelists a provider\n * @param provider The provider address\n */\n function whitelist(address provider) external;\n\n /**\n * @notice Delists a provider\n * @param provider The provider address\n */\n function delist(address provider) external;\n\n /**\n * @notice Sets the default provider\n * @param newDefaultProvider The new default provider address\n */\n function setDefaultProvider(address newDefaultProvider) external;\n}\n" + }, + "v2-core/interfaces/IERC721Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\n/**\n * @title IERC721Permit\n * @notice An interface for the ERC721 permit extension\n */\ninterface IERC721Permit is IERC721 {\n error InvalidSignature();\n error PermitExpired();\n\n /**\n * @notice The EIP-712 typehash for the permit struct used by the contract\n */\n function PERMIT_TYPEHASH() external pure returns (bytes32);\n\n /**\n * @notice The EIP-712 domain separator for this contract\n */\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n /**\n * @notice Approve the spender to transfer the given tokenId\n * @param spender The address to approve\n * @param tokenId The tokenId to approve\n * @param deadline The deadline for the signature\n * @param v The recovery id of the signature\n * @param r The r value of the signature\n * @param s The s value of the signature\n */\n function permit(address spender, uint256 tokenId, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @notice Get the current nonce for a token\n * @param tokenId The tokenId to get the nonce for\n * @return The current nonce\n */\n function nonces(uint256 tokenId) external view returns (uint256);\n}\n" + }, + "v2-core/interfaces/IHooks.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport {IBookManager} from \"./IBookManager.sol\";\nimport {OrderId} from \"../libraries/OrderId.sol\";\n\n/**\n * @title IHooks\n * @notice Interface for the hooks contract\n */\ninterface IHooks {\n /**\n * @notice Hook called before opening a new book\n * @param sender The sender of the open transaction\n * @param key The key of the book being opened\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function beforeOpen(address sender, IBookManager.BookKey calldata key, bytes calldata hookData)\n external\n returns (bytes4);\n\n /**\n * @notice Hook called after opening a new book\n * @param sender The sender of the open transaction\n * @param key The key of the book being opened\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function afterOpen(address sender, IBookManager.BookKey calldata key, bytes calldata hookData)\n external\n returns (bytes4);\n\n /**\n * @notice Hook called before making a new order\n * @param sender The sender of the make transaction\n * @param params The parameters of the make transaction\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function beforeMake(address sender, IBookManager.MakeParams calldata params, bytes calldata hookData)\n external\n returns (bytes4);\n\n /**\n * @notice Hook called after making a new order\n * @param sender The sender of the make transaction\n * @param params The parameters of the make transaction\n * @param orderId The id of the order that was made\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function afterMake(\n address sender,\n IBookManager.MakeParams calldata params,\n OrderId orderId,\n bytes calldata hookData\n ) external returns (bytes4);\n\n /**\n * @notice Hook called before taking an order\n * @param sender The sender of the take transaction\n * @param params The parameters of the take transaction\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function beforeTake(address sender, IBookManager.TakeParams calldata params, bytes calldata hookData)\n external\n returns (bytes4);\n\n /**\n * @notice Hook called after taking an order\n * @param sender The sender of the take transaction\n * @param params The parameters of the take transaction\n * @param takenUnit The unit that was taken\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function afterTake(\n address sender,\n IBookManager.TakeParams calldata params,\n uint64 takenUnit,\n bytes calldata hookData\n ) external returns (bytes4);\n\n /**\n * @notice Hook called before canceling an order\n * @param sender The sender of the cancel transaction\n * @param params The parameters of the cancel transaction\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function beforeCancel(address sender, IBookManager.CancelParams calldata params, bytes calldata hookData)\n external\n returns (bytes4);\n\n /**\n * @notice Hook called after canceling an order\n * @param sender The sender of the cancel transaction\n * @param params The parameters of the cancel transaction\n * @param canceledUnit The unit that was canceled\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function afterCancel(\n address sender,\n IBookManager.CancelParams calldata params,\n uint64 canceledUnit,\n bytes calldata hookData\n ) external returns (bytes4);\n\n /**\n * @notice Hook called before claiming an order\n * @param sender The sender of the claim transaction\n * @param orderId The id of the order being claimed\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function beforeClaim(address sender, OrderId orderId, bytes calldata hookData) external returns (bytes4);\n\n /**\n * @notice Hook called after claiming an order\n * @param sender The sender of the claim transaction\n * @param orderId The id of the order being claimed\n * @param claimedUnit The unit that was claimed\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function afterClaim(address sender, OrderId orderId, uint64 claimedUnit, bytes calldata hookData)\n external\n returns (bytes4);\n}\n" + }, + "v2-core/interfaces/ILocker.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ILocker\n * @notice Interface for the locker contract\n */\ninterface ILocker {\n /**\n * @notice Called by the book manager on `msg.sender` when a lock is acquired\n * @param data The data that was passed to the call to lock\n * @return Any data that you want to be returned from the lock call\n */\n function lockAcquired(address lockCaller, bytes calldata data) external returns (bytes memory);\n}\n" + }, + "v2-core/libraries/BookId.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {IBookManager} from \"../interfaces/IBookManager.sol\";\n\ntype BookId is uint192;\n\nlibrary BookIdLibrary {\n function toId(IBookManager.BookKey memory bookKey) internal pure returns (BookId id) {\n bytes32 hash = keccak256(abi.encode(bookKey));\n assembly {\n id := and(hash, 0xffffffffffffffffffffffffffffffffffffffffffffffff)\n }\n }\n}\n" + }, + "v2-core/libraries/Currency.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ntype Currency is address;\n\n/// @title CurrencyLibrary\n/// @dev This library allows for transferring and holding native tokens and ERC20 tokens\nlibrary CurrencyLibrary {\n using CurrencyLibrary for Currency;\n\n /// @notice Thrown when a native transfer fails\n error NativeTransferFailed();\n\n /// @notice Thrown when an ERC20 transfer fails\n error ERC20TransferFailed();\n\n Currency public constant NATIVE = Currency.wrap(address(0));\n\n function transfer(Currency currency, address to, uint256 amount) internal {\n // implementation from\n // https://github.com/transmissions11/solmate/blob/e8f96f25d48fe702117ce76c79228ca4f20206cb/src/utils/SafeTransferLib.sol\n\n bool success;\n if (currency.isNative()) {\n assembly {\n // Transfer the ETH and store if it succeeded or not.\n success := call(gas(), to, amount, 0, 0, 0, 0)\n }\n\n if (!success) revert NativeTransferFailed();\n } else {\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata into memory, beginning with the function selector.\n mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\n mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"to\" argument.\n mstore(add(freeMemoryPointer, 36), amount) // Append the \"amount\" argument. Masking not required as it's a full 32 byte type.\n\n success :=\n and(\n // Set success to whether the call reverted, if not we check it either\n // returned exactly 1 (can't just be non-zero data), or had no return data.\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n // Counterintuitively, this call must be positioned second to the or() call in the\n // surrounding and() call or else returndatasize() will be zero during the computation.\n call(gas(), currency, 0, freeMemoryPointer, 68, 0, 32)\n )\n }\n\n if (!success) revert ERC20TransferFailed();\n }\n }\n\n function balanceOfSelf(Currency currency) internal view returns (uint256) {\n if (currency.isNative()) return address(this).balance;\n else return IERC20(Currency.unwrap(currency)).balanceOf(address(this));\n }\n\n function equals(Currency currency, Currency other) internal pure returns (bool) {\n return Currency.unwrap(currency) == Currency.unwrap(other);\n }\n\n function isNative(Currency currency) internal pure returns (bool) {\n return Currency.unwrap(currency) == Currency.unwrap(NATIVE);\n }\n\n function toId(Currency currency) internal pure returns (uint256) {\n return uint160(Currency.unwrap(currency));\n }\n\n function fromId(uint256 id) internal pure returns (Currency) {\n return Currency.wrap(address(uint160(id)));\n }\n}\n" + }, + "v2-core/libraries/FeePolicy.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {Math} from \"./Math.sol\";\n\ntype FeePolicy is uint24;\n\nlibrary FeePolicyLibrary {\n uint256 internal constant RATE_PRECISION = 10 ** 6;\n int256 internal constant MAX_FEE_RATE = 500000;\n int256 internal constant MIN_FEE_RATE = -500000;\n\n uint256 internal constant RATE_MASK = 0x7fffff; // 23 bits\n\n error InvalidFeePolicy();\n\n function encode(bool usesQuote_, int24 rate_) internal pure returns (FeePolicy feePolicy) {\n if (rate_ > MAX_FEE_RATE || rate_ < MIN_FEE_RATE) {\n revert InvalidFeePolicy();\n }\n\n uint256 mask = usesQuote_ ? 1 << 23 : 0;\n assembly {\n feePolicy := or(mask, add(and(rate_, 0xffffff), MAX_FEE_RATE))\n }\n }\n\n function isValid(FeePolicy self) internal pure returns (bool) {\n int24 r = rate(self);\n\n return !(r > MAX_FEE_RATE || r < MIN_FEE_RATE);\n }\n\n function usesQuote(FeePolicy self) internal pure returns (bool f) {\n assembly {\n f := shr(23, self)\n }\n }\n\n function rate(FeePolicy self) internal pure returns (int24 r) {\n assembly {\n r := sub(and(self, RATE_MASK), MAX_FEE_RATE)\n }\n }\n\n function calculateFee(FeePolicy self, uint256 amount, bool reverseRounding) internal pure returns (int256 fee) {\n int24 r = rate(self);\n\n bool positive = r > 0;\n uint256 absRate;\n unchecked {\n absRate = uint256(uint24(positive ? r : -r));\n }\n // @dev absFee must be less than type(int256).max\n uint256 absFee = Math.divide(amount * absRate, RATE_PRECISION, reverseRounding ? !positive : positive);\n fee = positive ? int256(absFee) : -int256(absFee);\n }\n\n function calculateOriginalAmount(FeePolicy self, uint256 amount, bool reverseFee)\n internal\n pure\n returns (uint256 originalAmount)\n {\n int24 r = rate(self);\n\n bool positive = r > 0;\n uint256 divider;\n assembly {\n if reverseFee { r := sub(0, r) }\n divider := add(RATE_PRECISION, r)\n }\n originalAmount = Math.divide(amount * RATE_PRECISION, divider, positive);\n }\n}\n" + }, + "v2-core/libraries/Lockers.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.23;\n\nimport {IHooks} from \"../interfaces/IHooks.sol\";\n\n/// @author Clober\n/// @author Modified from Uniswap V4 (https://github.com/Uniswap/v4-core/tree/98680ebc1a654120e995d53a5b10ec6fe153066f)\n/// @notice Contains data about pool lockers.\n\n/// @dev This library manages a custom storage implementation for a queue\n/// that tracks current lockers. The \"sentinel\" storage slot for this data structure,\n/// always passed in as IPoolManager.LockData storage self, stores not just the current\n/// length of the queue but also the global count of non-zero deltas across all lockers.\n/// The values of the data structure start at OFFSET, and each value is a locker address.\nlibrary Lockers {\n /// struct LockData {\n /// /// @notice The current number of active lockers\n /// uint128 length;\n /// /// @notice The total number of nonzero deltas over all active + completed lockers\n /// uint128 nonzeroDeltaCount;\n /// }\n // uint256(keccak256(\"LockData\")) + 1\n uint256 internal constant LOCK_DATA_SLOT = 0x760a9a962ae3d184e99c0483cf5684fb3170f47116ca4f445c50209da4f4f907;\n\n // uint256(keccak256(\"Lockers\")) + 1\n uint256 internal constant LOCKERS_SLOT = 0x722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b1;\n\n // The number of slots per item in the lockers array\n uint256 internal constant LOCKER_STRUCT_SIZE = 2;\n\n // uint256(keccak256(\"HookAddress\")) + 1\n uint256 internal constant HOOK_ADDRESS_SLOT = 0xfcac7593714b88fec0c578a53e9f3f6e4b47eb26c9dcaa7eff23a3ac156be422;\n\n uint256 internal constant NONZERO_DELTA_COUNT_OFFSET = 2 ** 128;\n\n uint256 internal constant LENGTH_MASK = (1 << 128) - 1;\n\n /// @dev Pushes a locker onto the end of the queue, and updates the sentinel storage slot.\n function push(address locker, address lockCaller) internal {\n assembly {\n let data := tload(LOCK_DATA_SLOT)\n let l := and(data, LENGTH_MASK)\n\n // LOCKERS_SLOT + l * LOCKER_STRUCT_SIZE\n let indexToWrite := add(LOCKERS_SLOT, mul(l, LOCKER_STRUCT_SIZE))\n\n // in the next storage slot, write the locker and lockCaller\n tstore(indexToWrite, locker)\n tstore(add(indexToWrite, 1), lockCaller)\n\n // increase the length\n tstore(LOCK_DATA_SLOT, add(data, 1))\n }\n }\n\n function lockData() internal view returns (uint128 l, uint128 nonzeroDeltaCount) {\n assembly {\n let data := tload(LOCK_DATA_SLOT)\n l := and(data, LENGTH_MASK)\n nonzeroDeltaCount := shr(128, data)\n }\n }\n\n function length() internal view returns (uint128 l) {\n assembly {\n l := and(tload(LOCK_DATA_SLOT), LENGTH_MASK)\n }\n }\n\n /// @dev Pops a locker off the end of the queue. Note that no storage gets cleared.\n function pop() internal {\n assembly {\n let data := tload(LOCK_DATA_SLOT)\n let l := and(data, LENGTH_MASK)\n if iszero(l) {\n mstore(0x00, 0xf1c77ed0) // LockersPopFailed()\n revert(0x1c, 0x04)\n }\n\n // LOCKERS_SLOT + (l - 1) * LOCKER_STRUCT_SIZE\n let indexToWrite := add(LOCKERS_SLOT, mul(sub(l, 1), LOCKER_STRUCT_SIZE))\n\n // in the next storage slot, delete the locker and lockCaller\n tstore(indexToWrite, 0)\n tstore(add(indexToWrite, 1), 0)\n\n // decrease the length\n tstore(LOCK_DATA_SLOT, sub(data, 1))\n }\n }\n\n function getLocker(uint256 i) internal view returns (address locker) {\n assembly {\n // LOCKERS_SLOT + (i * LOCKER_STRUCT_SIZE)\n locker := tload(add(LOCKERS_SLOT, mul(i, LOCKER_STRUCT_SIZE)))\n }\n }\n\n function getLockCaller(uint256 i) internal view returns (address locker) {\n assembly {\n // LOCKERS_SLOT + (i * LOCKER_STRUCT_SIZE + 1)\n locker := tload(add(LOCKERS_SLOT, add(mul(i, LOCKER_STRUCT_SIZE), 1)))\n }\n }\n\n function getCurrentLocker() internal view returns (address) {\n unchecked {\n uint256 l = length();\n return l > 0 ? getLocker(l - 1) : address(0);\n }\n }\n\n function getCurrentLockCaller() internal view returns (address) {\n unchecked {\n uint256 l = length();\n return l > 0 ? getLockCaller(l - 1) : address(0);\n }\n }\n\n function incrementNonzeroDeltaCount() internal {\n assembly {\n tstore(LOCK_DATA_SLOT, add(tload(LOCK_DATA_SLOT), NONZERO_DELTA_COUNT_OFFSET))\n }\n }\n\n function decrementNonzeroDeltaCount() internal {\n assembly {\n tstore(LOCK_DATA_SLOT, sub(tload(LOCK_DATA_SLOT), NONZERO_DELTA_COUNT_OFFSET))\n }\n }\n\n function getCurrentHook() internal view returns (IHooks currentHook) {\n return IHooks(getHook(length()));\n }\n\n function getHook(uint256 i) internal view returns (address hook) {\n assembly {\n hook := tload(add(HOOK_ADDRESS_SLOT, i))\n }\n }\n\n function setCurrentHook(IHooks currentHook) internal returns (bool set) {\n // Set the hook address for the current locker if the address is 0.\n // If the address is nonzero, a hook has already been set for this lock, and is not allowed to be updated or cleared at the end of the call.\n if (address(getCurrentHook()) == address(0)) {\n uint256 l = length();\n assembly {\n tstore(add(HOOK_ADDRESS_SLOT, l), currentHook)\n }\n return true;\n }\n }\n\n function clearCurrentHook() internal {\n uint256 l = length();\n assembly {\n tstore(add(HOOK_ADDRESS_SLOT, l), 0)\n }\n }\n}\n" + }, + "v2-core/libraries/Math.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.0;\n\nlibrary Math {\n function divide(uint256 a, uint256 b, bool roundingUp) internal pure returns (uint256 ret) {\n // In the OrderBook contract code, b is never zero.\n assembly {\n ret := add(div(a, b), and(gt(mod(a, b), 0), roundingUp))\n }\n }\n\n /// @dev Returns `ln(x)`, denominated in `WAD`.\n /// Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln\n function lnWad(int256 x) internal pure returns (int256 r) {\n /// @solidity memory-safe-assembly\n assembly {\n // We want to convert `x` from `10**18` fixed point to `2**96` fixed point.\n // We do this by multiplying by `2**96 / 10**18`. But since\n // `ln(x * C) = ln(x) + ln(C)`, we can simply do nothing here\n // and add `ln(2**96 / 10**18)` at the end.\n\n // Compute `k = log2(x) - 96`, `r = 159 - k = 255 - log2(x) = 255 ^ log2(x)`.\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\n r := or(r, shl(3, lt(0xff, shr(r, x))))\n // We place the check here for more optimal stack operations.\n if iszero(sgt(x, 0)) {\n mstore(0x00, 0x1615e638) // `LnWadUndefined()`.\n revert(0x1c, 0x04)\n }\n // forgefmt: disable-next-item\n r := xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),\n 0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff))\n\n // Reduce range of x to (1, 2) * 2**96\n // ln(2^k * x) = k * ln(2) + ln(x)\n x := shr(159, shl(r, x))\n\n // Evaluate using a (8, 8)-term rational approximation.\n // `p` is made monic, we will multiply by a scale factor later.\n // forgefmt: disable-next-item\n let p := sub( // This heavily nested expression is to avoid stack-too-deep for via-ir.\n sar(96, mul(add(43456485725739037958740375743393,\n sar(96, mul(add(24828157081833163892658089445524,\n sar(96, mul(add(3273285459638523848632254066296,\n x), x))), x))), x)), 11111509109440967052023855526967)\n p := sub(sar(96, mul(p, x)), 45023709667254063763336534515857)\n p := sub(sar(96, mul(p, x)), 14706773417378608786704636184526)\n p := sub(mul(p, x), shl(96, 795164235651350426258249787498))\n // We leave `p` in `2**192` basis so we don't need to scale it back up for the division.\n\n // `q` is monic by convention.\n let q := add(5573035233440673466300451813936, x)\n q := add(71694874799317883764090561454958, sar(96, mul(x, q)))\n q := add(283447036172924575727196451306956, sar(96, mul(x, q)))\n q := add(401686690394027663651624208769553, sar(96, mul(x, q)))\n q := add(204048457590392012362485061816622, sar(96, mul(x, q)))\n q := add(31853899698501571402653359427138, sar(96, mul(x, q)))\n q := add(909429971244387300277376558375, sar(96, mul(x, q)))\n\n // `p / q` is in the range `(0, 0.125) * 2**96`.\n\n // Finalization, we need to:\n // - Multiply by the scale factor `s = 5.549…`.\n // - Add `ln(2**96 / 10**18)`.\n // - Add `k * ln(2)`.\n // - Multiply by `10**18 / 2**96 = 5**18 >> 78`.\n\n // The q polynomial is known not to have zeros in the domain.\n // No scaling required because p is already `2**96` too large.\n p := sdiv(p, q)\n // Multiply by the scaling factor: `s * 5**18 * 2**96`, base is now `5**18 * 2**192`.\n p := mul(1677202110996718588342820967067443963516166, p)\n // Add `ln(2) * k * 5**18 * 2**192`.\n // forgefmt: disable-next-item\n p := add(mul(16597577552685614221487285958193947469193820559219878177908093499208371, sub(159, r)), p)\n // Base conversion: mul `2**96 / (5**18 * 2**192)`.\n r := sdiv(p, 302231454903657293676544000000000000000000)\n }\n }\n}\n" + }, + "v2-core/libraries/OrderId.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.0;\n\nimport {Tick} from \"./Tick.sol\";\nimport {BookId} from \"./BookId.sol\";\n\ntype OrderId is uint256;\n\nlibrary OrderIdLibrary {\n /**\n * @dev Encode the order id.\n * @param bookId The book id.\n * @param tick The tick.\n * @param index The index.\n * @return id The order id.\n */\n function encode(BookId bookId, Tick tick, uint40 index) internal pure returns (OrderId id) {\n // @dev If we just use tick at the assembly code, the code will convert tick into bytes32.\n // e.g. When index == -2, the shifted value( shl(40, tick) ) will be\n // 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000 instead of 0xfffffffe0000000000\n // Therefore, we have to safely cast tick into uint256 first.\n uint256 _tick = uint256(uint24(Tick.unwrap(tick)));\n assembly {\n id := add(index, add(shl(40, _tick), shl(64, bookId)))\n }\n }\n\n function decode(OrderId id) internal pure returns (BookId bookId, Tick tick, uint40 index) {\n assembly {\n bookId := shr(64, id)\n tick := and(shr(40, id), 0xffffff)\n index := and(id, 0xffffffffff)\n }\n }\n\n function getBookId(OrderId id) internal pure returns (BookId bookId) {\n assembly {\n bookId := shr(64, id)\n }\n }\n\n function getTick(OrderId id) internal pure returns (Tick tick) {\n assembly {\n tick := and(shr(40, id), 0xffffff)\n }\n }\n\n function getIndex(OrderId id) internal pure returns (uint40 index) {\n assembly {\n index := and(id, 0xffffffffff)\n }\n }\n}\n" + }, + "v2-core/libraries/SignificantBit.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.0;\n\nlibrary SignificantBit {\n // http://supertech.csail.mit.edu/papers/debruijn.pdf\n uint256 internal constant DEBRUIJN_SEQ = 0x818283848586878898A8B8C8D8E8F929395969799A9B9D9E9FAAEB6BEDEEFF;\n bytes internal constant DEBRUIJN_INDEX =\n hex\"0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8\";\n\n /**\n * @notice Finds the index of the least significant bit.\n * @param x The value to compute the least significant bit for. Must be a non-zero value.\n * @return ret The index of the least significant bit.\n */\n function leastSignificantBit(uint256 x) internal pure returns (uint8) {\n require(x > 0);\n uint256 index;\n assembly {\n index := shr(248, mul(and(x, add(not(x), 1)), DEBRUIJN_SEQ))\n }\n return uint8(DEBRUIJN_INDEX[index]); // can optimize with CODECOPY opcode\n }\n\n function mostSignificantBit(uint256 x) internal pure returns (uint8 msb) {\n require(x > 0);\n assembly {\n let f := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n x := shr(f, x)\n f := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n x := shr(f, x)\n f := shl(5, gt(x, 0xFFFFFFFF))\n msb := or(msb, f)\n x := shr(f, x)\n f := shl(4, gt(x, 0xFFFF))\n msb := or(msb, f)\n x := shr(f, x)\n f := shl(3, gt(x, 0xFF))\n msb := or(msb, f)\n x := shr(f, x)\n f := shl(2, gt(x, 0xF))\n msb := or(msb, f)\n x := shr(f, x)\n f := shl(1, gt(x, 0x3))\n msb := or(msb, f)\n x := shr(f, x)\n f := gt(x, 0x1)\n msb := or(msb, f)\n }\n }\n}\n" + }, + "v2-core/libraries/Tick.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {Math} from \"./Math.sol\";\n\ntype Tick is int24;\n\nlibrary TickLibrary {\n using Math for *;\n using TickLibrary for Tick;\n\n error InvalidTick();\n error InvalidPrice();\n error TickOverflow();\n\n int24 internal constant MAX_TICK = 2 ** 19 - 1;\n int24 internal constant MIN_TICK = -MAX_TICK;\n\n uint256 internal constant MIN_PRICE = 1350587;\n uint256 internal constant MAX_PRICE = 4647684107270898330752324302845848816923571339324334;\n\n uint256 private constant _R0 = 0xfff97272373d413259a46990;\n uint256 private constant _R1 = 0xfff2e50f5f656932ef12357c;\n uint256 private constant _R2 = 0xffe5caca7e10e4e61c3624ea;\n uint256 private constant _R3 = 0xffcb9843d60f6159c9db5883;\n uint256 private constant _R4 = 0xff973b41fa98c081472e6896;\n uint256 private constant _R5 = 0xff2ea16466c96a3843ec78b3;\n uint256 private constant _R6 = 0xfe5dee046a99a2a811c461f1;\n uint256 private constant _R7 = 0xfcbe86c7900a88aedcffc83b;\n uint256 private constant _R8 = 0xf987a7253ac413176f2b074c;\n uint256 private constant _R9 = 0xf3392b0822b70005940c7a39;\n uint256 private constant _R10 = 0xe7159475a2c29b7443b29c7f;\n uint256 private constant _R11 = 0xd097f3bdfd2022b8845ad8f7;\n uint256 private constant _R12 = 0xa9f746462d870fdf8a65dc1f;\n uint256 private constant _R13 = 0x70d869a156d2a1b890bb3df6;\n uint256 private constant _R14 = 0x31be135f97d08fd981231505;\n uint256 private constant _R15 = 0x9aa508b5b7a84e1c677de54;\n uint256 private constant _R16 = 0x5d6af8dedb81196699c329;\n uint256 private constant _R17 = 0x2216e584f5fa1ea92604;\n uint256 private constant _R18 = 0x48a170391f7dc42;\n uint256 private constant _R19 = 0x149b34;\n\n function validateTick(Tick tick) internal pure {\n if (Tick.unwrap(tick) > MAX_TICK || Tick.unwrap(tick) < MIN_TICK) revert InvalidTick();\n }\n\n modifier validatePrice(uint256 price) {\n if (price > MAX_PRICE || price < MIN_PRICE) revert InvalidPrice();\n _;\n }\n\n function fromPrice(uint256 price) internal pure validatePrice(price) returns (Tick) {\n unchecked {\n int24 tick = int24((int256(price).lnWad() * 42951820407860) / 2 ** 128);\n if (toPrice(Tick.wrap(tick)) > price) return Tick.wrap(tick - 1);\n return Tick.wrap(tick);\n }\n }\n\n function toPrice(Tick tick) internal pure returns (uint256 price) {\n validateTick(tick);\n int24 tickValue = Tick.unwrap(tick);\n uint256 absTick = uint24(tickValue < 0 ? -tickValue : tickValue);\n\n unchecked {\n if (absTick & 0x1 != 0) price = _R0;\n else price = 1 << 96;\n if (absTick & 0x2 != 0) price = (price * _R1) >> 96;\n if (absTick & 0x4 != 0) price = (price * _R2) >> 96;\n if (absTick & 0x8 != 0) price = (price * _R3) >> 96;\n if (absTick & 0x10 != 0) price = (price * _R4) >> 96;\n if (absTick & 0x20 != 0) price = (price * _R5) >> 96;\n if (absTick & 0x40 != 0) price = (price * _R6) >> 96;\n if (absTick & 0x80 != 0) price = (price * _R7) >> 96;\n if (absTick & 0x100 != 0) price = (price * _R8) >> 96;\n if (absTick & 0x200 != 0) price = (price * _R9) >> 96;\n if (absTick & 0x400 != 0) price = (price * _R10) >> 96;\n if (absTick & 0x800 != 0) price = (price * _R11) >> 96;\n if (absTick & 0x1000 != 0) price = (price * _R12) >> 96;\n if (absTick & 0x2000 != 0) price = (price * _R13) >> 96;\n if (absTick & 0x4000 != 0) price = (price * _R14) >> 96;\n if (absTick & 0x8000 != 0) price = (price * _R15) >> 96;\n if (absTick & 0x10000 != 0) price = (price * _R16) >> 96;\n if (absTick & 0x20000 != 0) price = (price * _R17) >> 96;\n if (absTick & 0x40000 != 0) price = (price * _R18) >> 96;\n }\n if (tickValue > 0) price = 0x1000000000000000000000000000000000000000000000000 / price;\n }\n\n function gt(Tick a, Tick b) internal pure returns (bool) {\n return Tick.unwrap(a) > Tick.unwrap(b);\n }\n\n function baseToQuote(Tick tick, uint256 base, bool roundingUp) internal pure returns (uint256) {\n return Math.divide((base * tick.toPrice()), 1 << 96, roundingUp);\n }\n\n function quoteToBase(Tick tick, uint256 quote, bool roundingUp) internal pure returns (uint256) {\n // @dev quote = unit(uint64) * unitSize(uint64) < 2^96\n // We don't need to check overflow here\n return Math.divide(quote << 96, tick.toPrice(), roundingUp);\n }\n}\n" + } + }, + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 1000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/8453/Arbitrage.json b/deployments/8453/Arbitrage.json new file mode 100644 index 0000000..7172d26 --- /dev/null +++ b/deployments/8453/Arbitrage.json @@ -0,0 +1,481 @@ +{ + "address": "0x5489922f8312c812fBB7184EbF70b9dbFAeed9D4", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "bookManager_", + "type": "address" + }, + { + "internalType": "address", + "name": "initialOwner_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ERC20TransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAccess", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTick", + "type": "error" + }, + { + "inputs": [], + "name": "NativeTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "NotOperator", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyGuardReentrantCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "bits", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintDowncast", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintToInt", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "status", + "type": "bool" + } + ], + "name": "SetOperator", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "BookId", + "name": "id", + "type": "uint192" + }, + { + "internalType": "address", + "name": "router", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "arbitrage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "bookManager", + "outputs": [ + { + "internalType": "contract IBookManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isOperator", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "lockAcquired", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "status", + "type": "bool" + } + ], + "name": "setOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "Currency", + "name": "currency", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xde2b6359c2e94fac2c9656de1f1867af1f13da71e726dabde7b265e0ee723465", + "receipt": { + "to": null, + "from": "0x4587dd6356d7293E5f10db4D853332BD5b218C0B", + "contractAddress": "0x5489922f8312c812fBB7184EbF70b9dbFAeed9D4", + "transactionIndex": 25, + "gasUsed": "1709221", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000002040020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000400000000000000000000020000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x0aa7efc1de3a06901646231f2ea3fb1c89a8b60e2af7a20006f3ee2316f96437", + "transactionHash": "0xde2b6359c2e94fac2c9656de1f1867af1f13da71e726dabde7b265e0ee723465", + "logs": [ + { + "transactionIndex": 25, + "blockNumber": 17461328, + "transactionHash": "0xde2b6359c2e94fac2c9656de1f1867af1f13da71e726dabde7b265e0ee723465", + "address": "0x5489922f8312c812fBB7184EbF70b9dbFAeed9D4", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000fb976bae0b3ef71843f1c6c63da7df2e44b3836d" + ], + "data": "0x", + "logIndex": 89, + "blockHash": "0x0aa7efc1de3a06901646231f2ea3fb1c89a8b60e2af7a20006f3ee2316f96437" + } + ], + "blockNumber": 17461328, + "cumulativeGasUsed": "7963730", + "status": 1, + "byzantium": true + }, + "args": [ + "0x382CCccbD3b142D7DA063bF68cd0c89634767F76", + "0xfb976Bae0b3Ef71843F1c6c63da7Df2e44B3836d" + ], + "numDeployments": 1, + "solcInputHash": "e634729b678ce078f381c6f26baf2f0d", + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bookManager_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"initialOwner_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ERC20TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAccess\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTick\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativeTransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotOperator\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"bits\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SafeCastOverflowedUintDowncast\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"SafeCastOverflowedUintToInt\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"SetOperator\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"BookId\",\"name\":\"id\",\"type\":\"uint192\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"arbitrage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bookManager\",\"outputs\":[{\"internalType\":\"contract IBookManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isOperator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"lockAcquired\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"setOperator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"Currency\",\"name\":\"currency\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"OwnableInvalidOwner(address)\":[{\"details\":\"The owner is not a valid owner account. (eg. `address(0)`)\"}],\"OwnableUnauthorizedAccount(address)\":[{\"details\":\"The caller account is not authorized to perform an operation.\"}],\"SafeCastOverflowedUintDowncast(uint8,uint256)\":[{\"details\":\"Value doesn't fit in an uint of `bits` size.\"}],\"SafeCastOverflowedUintToInt(uint256)\":[{\"details\":\"An uint value doesn't fit in an int of `bits` size.\"}]},\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"errors\":{\"ERC20TransferFailed()\":[{\"notice\":\"Thrown when an ERC20 transfer fails\"}],\"NativeTransferFailed()\":[{\"notice\":\"Thrown when a native transfer fails\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/Arbitrage.sol\":\"Arbitrage\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Context} from \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initial owner is set to the address provided by the deployer. This can\\n * later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n /**\\n * @dev The caller account is not authorized to perform an operation.\\n */\\n error OwnableUnauthorizedAccount(address account);\\n\\n /**\\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\\n */\\n error OwnableInvalidOwner(address owner);\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\\n */\\n constructor(address initialOwner) {\\n if (initialOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(initialOwner);\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n if (owner() != _msgSender()) {\\n revert OwnableUnauthorizedAccount(_msgSender());\\n }\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n if (newOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable2Step.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Ownable} from \\\"./Ownable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * This extension of the {Ownable} contract includes a two-step mechanism to transfer\\n * ownership, where the new owner must call {acceptOwnership} in order to replace the\\n * old one. This can help prevent common mistakes, such as transfers of ownership to\\n * incorrect accounts, or to contracts that are unable to interact with the\\n * permission system.\\n *\\n * The initial owner is specified at deployment time in the constructor for `Ownable`. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2Step is Ownable {\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n if (pendingOwner() != sender) {\\n revert OwnableUnauthorizedAccount(sender);\\n }\\n _transferOwnership(sender);\\n }\\n}\\n\",\"keccak256\":\"0x08b074ae1b12e70ce24d1335086ec5a418934311a6771d9f61fe24d392050e12\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\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 value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens as the allowance of `spender` over the\\n * 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 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` 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 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xee2337af2dc162a973b4be6d3f7c16f06298259e0af48c5470d2839bfa8a22f4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC-721 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\\n * 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 ERC-721 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\\n * {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\\n * 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 ERC-721\\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 address zero.\\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\",\"keccak256\":\"0xe0e3a2099f2e2ce3579dd35548f613928739642058dfec95b1745f93364ce3de\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC721} from \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x37d1aaaa5a2908a09e9dcf56a26ddf762ecf295afb5964695937344fc6802ce1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n function _contextSuffixLength() internal view virtual returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\\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[ERC section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xc859863e3bda7ec3cddf6dafe2ffe91bcbe648d1395b856b839c32ee9617c44c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeCast {\\n /**\\n * @dev Value doesn't fit in an uint of `bits` size.\\n */\\n error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\\n\\n /**\\n * @dev An int value doesn't fit in an uint of `bits` size.\\n */\\n error SafeCastOverflowedIntToUint(int256 value);\\n\\n /**\\n * @dev Value doesn't fit in an int of `bits` size.\\n */\\n error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\\n\\n /**\\n * @dev An uint value doesn't fit in an int of `bits` size.\\n */\\n error SafeCastOverflowedUintToInt(uint256 value);\\n\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n if (value > type(uint248).max) {\\n revert SafeCastOverflowedUintDowncast(248, value);\\n }\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n if (value > type(uint240).max) {\\n revert SafeCastOverflowedUintDowncast(240, value);\\n }\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n if (value > type(uint232).max) {\\n revert SafeCastOverflowedUintDowncast(232, value);\\n }\\n return uint232(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n if (value > type(uint224).max) {\\n revert SafeCastOverflowedUintDowncast(224, value);\\n }\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n if (value > type(uint216).max) {\\n revert SafeCastOverflowedUintDowncast(216, value);\\n }\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n if (value > type(uint208).max) {\\n revert SafeCastOverflowedUintDowncast(208, value);\\n }\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n if (value > type(uint200).max) {\\n revert SafeCastOverflowedUintDowncast(200, value);\\n }\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n if (value > type(uint192).max) {\\n revert SafeCastOverflowedUintDowncast(192, value);\\n }\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n if (value > type(uint184).max) {\\n revert SafeCastOverflowedUintDowncast(184, value);\\n }\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n if (value > type(uint176).max) {\\n revert SafeCastOverflowedUintDowncast(176, value);\\n }\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n if (value > type(uint168).max) {\\n revert SafeCastOverflowedUintDowncast(168, value);\\n }\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n if (value > type(uint160).max) {\\n revert SafeCastOverflowedUintDowncast(160, value);\\n }\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n if (value > type(uint152).max) {\\n revert SafeCastOverflowedUintDowncast(152, value);\\n }\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n if (value > type(uint144).max) {\\n revert SafeCastOverflowedUintDowncast(144, value);\\n }\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n if (value > type(uint136).max) {\\n revert SafeCastOverflowedUintDowncast(136, value);\\n }\\n return uint136(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint128 from uint256, reverting on\\n * overflow (when the input is greater than largest uint128).\\n *\\n * Counterpart to Solidity's `uint128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n */\\n function toUint128(uint256 value) internal pure returns (uint128) {\\n if (value > type(uint128).max) {\\n revert SafeCastOverflowedUintDowncast(128, value);\\n }\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n if (value > type(uint120).max) {\\n revert SafeCastOverflowedUintDowncast(120, value);\\n }\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n if (value > type(uint112).max) {\\n revert SafeCastOverflowedUintDowncast(112, value);\\n }\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n if (value > type(uint104).max) {\\n revert SafeCastOverflowedUintDowncast(104, value);\\n }\\n return uint104(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n if (value > type(uint96).max) {\\n revert SafeCastOverflowedUintDowncast(96, value);\\n }\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n if (value > type(uint88).max) {\\n revert SafeCastOverflowedUintDowncast(88, value);\\n }\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n if (value > type(uint80).max) {\\n revert SafeCastOverflowedUintDowncast(80, value);\\n }\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n if (value > type(uint72).max) {\\n revert SafeCastOverflowedUintDowncast(72, value);\\n }\\n return uint72(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint64 from uint256, reverting on\\n * overflow (when the input is greater than largest uint64).\\n *\\n * Counterpart to Solidity's `uint64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n */\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n if (value > type(uint64).max) {\\n revert SafeCastOverflowedUintDowncast(64, value);\\n }\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n if (value > type(uint56).max) {\\n revert SafeCastOverflowedUintDowncast(56, value);\\n }\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n if (value > type(uint48).max) {\\n revert SafeCastOverflowedUintDowncast(48, value);\\n }\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n if (value > type(uint40).max) {\\n revert SafeCastOverflowedUintDowncast(40, value);\\n }\\n return uint40(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint32 from uint256, reverting on\\n * overflow (when the input is greater than largest uint32).\\n *\\n * Counterpart to Solidity's `uint32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n */\\n function toUint32(uint256 value) internal pure returns (uint32) {\\n if (value > type(uint32).max) {\\n revert SafeCastOverflowedUintDowncast(32, value);\\n }\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n if (value > type(uint24).max) {\\n revert SafeCastOverflowedUintDowncast(24, value);\\n }\\n return uint24(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint16 from uint256, reverting on\\n * overflow (when the input is greater than largest uint16).\\n *\\n * Counterpart to Solidity's `uint16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n */\\n function toUint16(uint256 value) internal pure returns (uint16) {\\n if (value > type(uint16).max) {\\n revert SafeCastOverflowedUintDowncast(16, value);\\n }\\n return uint16(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint8 from uint256, reverting on\\n * overflow (when the input is greater than largest uint8).\\n *\\n * Counterpart to Solidity's `uint8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n */\\n function toUint8(uint256 value) internal pure returns (uint8) {\\n if (value > type(uint8).max) {\\n revert SafeCastOverflowedUintDowncast(8, value);\\n }\\n return uint8(value);\\n }\\n\\n /**\\n * @dev Converts a signed int256 into an unsigned uint256.\\n *\\n * Requirements:\\n *\\n * - input must be greater than or equal to 0.\\n */\\n function toUint256(int256 value) internal pure returns (uint256) {\\n if (value < 0) {\\n revert SafeCastOverflowedIntToUint(value);\\n }\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(248, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(240, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(232, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(224, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(216, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(208, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(200, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(192, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(184, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(176, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(168, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(160, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(152, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(144, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(136, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int128 from int256, reverting on\\n * overflow (when the input is less than smallest int128 or\\n * greater than largest int128).\\n *\\n * Counterpart to Solidity's `int128` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 128 bits\\n */\\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(128, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(120, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(112, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(104, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(96, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(88, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(80, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(72, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int64 from int256, reverting on\\n * overflow (when the input is less than smallest int64 or\\n * greater than largest int64).\\n *\\n * Counterpart to Solidity's `int64` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 64 bits\\n */\\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(64, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(56, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(48, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(40, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int32 from int256, reverting on\\n * overflow (when the input is less than smallest int32 or\\n * greater than largest int32).\\n *\\n * Counterpart to Solidity's `int32` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 32 bits\\n */\\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(32, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(24, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int16 from int256, reverting on\\n * overflow (when the input is less than smallest int16 or\\n * greater than largest int16).\\n *\\n * Counterpart to Solidity's `int16` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 16 bits\\n */\\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(16, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int8 from int256, reverting on\\n * overflow (when the input is less than smallest int8 or\\n * greater than largest int8).\\n *\\n * Counterpart to Solidity's `int8` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 8 bits\\n */\\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(8, value);\\n }\\n }\\n\\n /**\\n * @dev Converts an unsigned uint256 into a signed int256.\\n *\\n * Requirements:\\n *\\n * - input must be less than or equal to maxInt256.\\n */\\n function toInt256(uint256 value) internal pure returns (int256) {\\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n if (value > uint256(type(int256).max)) {\\n revert SafeCastOverflowedUintToInt(value);\\n }\\n return int256(value);\\n }\\n\\n /**\\n * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\\n */\\n function toUint(bool b) internal pure returns (uint256 u) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n u := iszero(iszero(b))\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8cd59334ed58b8884cd1f775afc9400db702e674e5d6a7a438c655b9de788d7e\",\"license\":\"MIT\"},\"src/Arbitrage.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {Ownable, Ownable2Step} from \\\"@openzeppelin/contracts/access/Ownable2Step.sol\\\";\\nimport {IBookManager} from \\\"v2-core/interfaces/IBookManager.sol\\\";\\nimport {ILocker} from \\\"v2-core/interfaces/ILocker.sol\\\";\\nimport {IHooks} from \\\"v2-core/interfaces/IHooks.sol\\\";\\nimport {BookId, BookIdLibrary} from \\\"v2-core/libraries/BookId.sol\\\";\\nimport {Currency, CurrencyLibrary} from \\\"v2-core/libraries/Currency.sol\\\";\\nimport {FeePolicy, FeePolicyLibrary} from \\\"v2-core/libraries/FeePolicy.sol\\\";\\nimport {Tick, TickLibrary} from \\\"v2-core/libraries/Tick.sol\\\";\\nimport {ReentrancyGuard} from \\\"./libraries/ReentrancyGuard.sol\\\";\\nimport {IArbitrage} from \\\"./interfaces/IArbitrage.sol\\\";\\n\\ncontract Arbitrage is IArbitrage, Ownable2Step, ILocker, ReentrancyGuard {\\n using TickLibrary for Tick;\\n using SafeCast for uint256;\\n using CurrencyLibrary for Currency;\\n using FeePolicyLibrary for FeePolicy;\\n\\n IBookManager public immutable bookManager;\\n\\n mapping(address => bool) public isOperator;\\n\\n modifier onlyOperator() {\\n if (!isOperator[msg.sender]) revert NotOperator();\\n _;\\n }\\n\\n constructor(address bookManager_, address initialOwner_) Ownable(initialOwner_) {\\n bookManager = IBookManager(bookManager_);\\n }\\n\\n function setOperator(address operator, bool status) external onlyOwner {\\n isOperator[operator] = status;\\n emit SetOperator(operator, status);\\n }\\n\\n function lockAcquired(address sender, bytes memory data) external nonReentrant returns (bytes memory) {\\n if (msg.sender != address(bookManager) || sender != address(this)) revert InvalidAccess();\\n address user;\\n BookId id;\\n address router;\\n (user, id, router, data) = abi.decode(data, (address, BookId, address, bytes));\\n\\n IBookManager.BookKey memory key = bookManager.getBookKey(id);\\n uint256 max;\\n bool success;\\n bytes memory returnData;\\n if (key.quote.isNative()) {\\n max = address(bookManager).balance;\\n bookManager.withdraw(key.quote, address(this), max);\\n (success, returnData) = router.call{value: max}(data);\\n } else {\\n IERC20 quote = IERC20(Currency.unwrap(key.quote));\\n max = quote.balanceOf(address(bookManager));\\n quote.approve(router, max);\\n (success, returnData) = router.call(data);\\n quote.approve(router, 0);\\n }\\n if (!success) revert();\\n\\n uint256 quoteAmount = max - key.quote.balanceOfSelf();\\n uint256 baseAmount = key.base.balanceOfSelf();\\n uint256 spentBaseAmount;\\n uint256 price;\\n if (key.takerPolicy.usesQuote()) {\\n quoteAmount = uint256(quoteAmount.toInt256() + key.takerPolicy.calculateFee(quoteAmount, false));\\n price = (quoteAmount << 96) / baseAmount;\\n } else {\\n price = (quoteAmount << 96) / key.takerPolicy.calculateOriginalAmount(baseAmount, false);\\n }\\n\\n while (spentBaseAmount < baseAmount && !bookManager.isEmpty(id)) {\\n Tick tick = bookManager.getHighest(id);\\n if (price >= tick.toPrice()) break; // Did not consider fees.\\n uint256 maxAmount;\\n unchecked {\\n if (key.takerPolicy.usesQuote()) {\\n maxAmount = baseAmount - spentBaseAmount;\\n } else {\\n maxAmount = key.takerPolicy.calculateOriginalAmount(baseAmount - spentBaseAmount, false);\\n }\\n }\\n maxAmount = tick.baseToQuote(maxAmount, false) / key.unitSize;\\n if (maxAmount == 0) break;\\n (, uint256 amount) =\\n bookManager.take(IBookManager.TakeParams({key: key, tick: tick, maxUnit: maxAmount.toUint64()}), \\\"\\\");\\n if (amount == 0) break;\\n spentBaseAmount += amount;\\n }\\n\\n _settleCurrency(user, key.quote);\\n _settleCurrency(user, key.base);\\n\\n return \\\"\\\";\\n }\\n\\n function arbitrage(BookId id, address router, bytes calldata data) external onlyOperator {\\n bookManager.lock(address(this), abi.encode(msg.sender, id, router, data));\\n }\\n\\n function _settleCurrency(address user, Currency currency) internal {\\n int256 currencyDelta = -bookManager.getCurrencyDelta(address(this), currency);\\n if (currencyDelta > 0) {\\n currency.transfer(address(bookManager), uint256(currencyDelta));\\n }\\n bookManager.settle(currency);\\n currency.transfer(user, currency.balanceOfSelf());\\n }\\n\\n function withdrawToken(Currency currency, uint256 amount, address recipient) external onlyOwner {\\n currency.transfer(recipient, amount);\\n }\\n\\n receive() external payable {}\\n}\\n\",\"keccak256\":\"0xbefc5d0001a721e18fbc562ad464d29b02b06183087315578ee72e7242ab7fee\",\"license\":\"GPL-2.0-or-later\"},\"src/interfaces/IArbitrage.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.0;\\n\\nimport {BookId} from \\\"v2-core/libraries/BookId.sol\\\";\\nimport {Currency} from \\\"v2-core/libraries/Currency.sol\\\";\\n\\ninterface IArbitrage {\\n error InvalidAccess();\\n error NotOperator();\\n\\n event SetOperator(address indexed operator, bool status);\\n\\n function setOperator(address operator, bool status) external;\\n\\n function arbitrage(BookId id, address router, bytes calldata data) external;\\n\\n function withdrawToken(Currency currency, uint256 amount, address recipient) external;\\n}\\n\",\"keccak256\":\"0x6a3388787f1777d2b29ee3a57e742acc79f2dbdd6aebdd4bbe9c2723b024682c\",\"license\":\"UNLICENSED\"},\"src/libraries/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.24;\\n\\nabstract contract ReentrancyGuard {\\n // uint256(keccak256(\\\"ReentrancyGuard\\\")) - 1\\n uint256 internal constant REENTRANCY_GUARD_SLOT = 0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4;\\n\\n error ReentrancyGuardReentrantCall();\\n\\n modifier nonReentrant() {\\n _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n if (_reentrancyGuardEntered()) {\\n revert ReentrancyGuardReentrantCall();\\n }\\n assembly {\\n // Any calls to nonReentrant after this point will fail\\n tstore(REENTRANCY_GUARD_SLOT, 1)\\n }\\n }\\n\\n function _nonReentrantAfter() private {\\n assembly {\\n tstore(REENTRANCY_GUARD_SLOT, 0)\\n }\\n }\\n\\n function _reentrancyGuardEntered() internal view returns (bool isEntered) {\\n assembly {\\n isEntered := tload(REENTRANCY_GUARD_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4a29368336cca301ffb393ab2b667b311cca443f888bc4d2593261f47114ea1b\",\"license\":\"GPL-2.0-or-later\"},\"v2-core/interfaces/IBookManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\nimport {BookId} from \\\"../libraries/BookId.sol\\\";\\nimport {Currency} from \\\"../libraries/Currency.sol\\\";\\nimport {OrderId} from \\\"../libraries/OrderId.sol\\\";\\nimport {Tick} from \\\"../libraries/Tick.sol\\\";\\nimport {FeePolicy} from \\\"../libraries/FeePolicy.sol\\\";\\nimport {IERC721Permit} from \\\"./IERC721Permit.sol\\\";\\nimport {IHooks} from \\\"./IHooks.sol\\\";\\n\\n/**\\n * @title IBookManager\\n * @notice The interface for the BookManager contract\\n */\\ninterface IBookManager is IERC721Metadata, IERC721Permit {\\n error InvalidUnitSize();\\n error InvalidFeePolicy();\\n error InvalidProvider(address provider);\\n error LockedBy(address locker, address hook);\\n error CurrencyNotSettled();\\n\\n /**\\n * @notice Event emitted when a new book is opened\\n * @param id The book id\\n * @param base The base currency\\n * @param quote The quote currency\\n * @param unitSize The unit size of the book\\n * @param makerPolicy The maker fee policy\\n * @param takerPolicy The taker fee policy\\n * @param hooks The hooks contract\\n */\\n event Open(\\n BookId indexed id,\\n Currency indexed base,\\n Currency indexed quote,\\n uint64 unitSize,\\n FeePolicy makerPolicy,\\n FeePolicy takerPolicy,\\n IHooks hooks\\n );\\n\\n /**\\n * @notice Event emitted when a new order is made\\n * @param bookId The book id\\n * @param user The user address\\n * @param tick The order tick\\n * @param orderIndex The order index\\n * @param unit The order unit\\n * @param provider The provider address\\n */\\n event Make(\\n BookId indexed bookId, address indexed user, Tick tick, uint256 orderIndex, uint64 unit, address provider\\n );\\n\\n /**\\n * @notice Event emitted when an order is taken\\n * @param bookId The book id\\n * @param user The user address\\n * @param tick The order tick\\n * @param unit The order unit\\n */\\n event Take(BookId indexed bookId, address indexed user, Tick tick, uint64 unit);\\n\\n /**\\n * @notice Event emitted when an order is canceled\\n * @param orderId The order id\\n * @param unit The canceled unit\\n */\\n event Cancel(OrderId indexed orderId, uint64 unit);\\n\\n /**\\n * @notice Event emitted when an order is claimed\\n * @param orderId The order id\\n * @param unit The claimed unit\\n */\\n event Claim(OrderId indexed orderId, uint64 unit);\\n\\n /**\\n * @notice Event emitted when a provider is whitelisted\\n * @param provider The provider address\\n */\\n event Whitelist(address indexed provider);\\n\\n /**\\n * @notice Event emitted when a provider is delisted\\n * @param provider The provider address\\n */\\n event Delist(address indexed provider);\\n\\n /**\\n * @notice Event emitted when a provider collects fees\\n * @param provider The provider address\\n * @param recipient The recipient address\\n * @param currency The currency\\n * @param amount The collected amount\\n */\\n event Collect(address indexed provider, address indexed recipient, Currency indexed currency, uint256 amount);\\n\\n /**\\n * @notice Event emitted when new default provider is set\\n * @param newDefaultProvider The new default provider address\\n */\\n event SetDefaultProvider(address indexed newDefaultProvider);\\n\\n /**\\n * @notice This structure represents a unique identifier for a book in the BookManager.\\n * @param base The base currency of the book\\n * @param unitSize The unit size of the book\\n * @param quote The quote currency of the book\\n * @param makerPolicy The maker fee policy of the book\\n * @param hooks The hooks contract of the book\\n * @param takerPolicy The taker fee policy of the book\\n */\\n struct BookKey {\\n Currency base;\\n uint64 unitSize;\\n Currency quote;\\n FeePolicy makerPolicy;\\n IHooks hooks;\\n FeePolicy takerPolicy;\\n }\\n\\n /**\\n * @notice Returns the base URI\\n * @return The base URI\\n */\\n function baseURI() external view returns (string memory);\\n\\n /**\\n * @notice Returns the contract URI\\n * @return The contract URI\\n */\\n function contractURI() external view returns (string memory);\\n\\n /**\\n * @notice Returns the default provider\\n * @return The default provider\\n */\\n function defaultProvider() external view returns (address);\\n\\n /**\\n * @notice Returns the total reserves of a given currency\\n * @param currency The currency in question\\n * @return The total reserves amount\\n */\\n function reservesOf(Currency currency) external view returns (uint256);\\n\\n /**\\n * @notice Checks if a provider is whitelisted\\n * @param provider The address of the provider\\n * @return True if the provider is whitelisted, false otherwise\\n */\\n function isWhitelisted(address provider) external view returns (bool);\\n\\n /**\\n * @notice Verifies if an owner has authorized a spender for a token\\n * @param owner The address of the token owner\\n * @param spender The address of the spender\\n * @param tokenId The token ID\\n */\\n function checkAuthorized(address owner, address spender, uint256 tokenId) external view;\\n\\n /**\\n * @notice Calculates the amount owed to a provider in a given currency\\n * @param provider The provider's address\\n * @param currency The currency in question\\n * @return The owed amount\\n */\\n function tokenOwed(address provider, Currency currency) external view returns (uint256);\\n\\n /**\\n * @notice Calculates the currency balance changes for a given locker\\n * @param locker The address of the locker\\n * @param currency The currency in question\\n * @return The net change in currency balance\\n */\\n function getCurrencyDelta(address locker, Currency currency) external view returns (int256);\\n\\n /**\\n * @notice Retrieves the book key for a given book ID\\n * @param id The book ID\\n * @return The book key\\n */\\n function getBookKey(BookId id) external view returns (BookKey memory);\\n\\n /**\\n * @notice This structure represents a current status for an order in the BookManager.\\n * @param provider The provider of the order\\n * @param open The open unit of the order\\n * @param claimable The claimable unit of the order\\n */\\n struct OrderInfo {\\n address provider;\\n uint64 open;\\n uint64 claimable;\\n }\\n\\n /**\\n * @notice Provides information about an order\\n * @param id The order ID\\n * @return Order information including provider, open status, and claimable unit\\n */\\n function getOrder(OrderId id) external view returns (OrderInfo memory);\\n\\n /**\\n * @notice Retrieves the locker and caller addresses for a given lock\\n * @param i The index of the lock\\n * @return locker The locker's address\\n * @return lockCaller The caller's address\\n */\\n function getLock(uint256 i) external view returns (address locker, address lockCaller);\\n\\n /**\\n * @notice Provides the lock data\\n * @return The lock data including necessary numeric values\\n */\\n function getLockData() external view returns (uint128, uint128);\\n\\n /**\\n * @notice Returns the depth of a given book ID and tick\\n * @param id The book ID\\n * @param tick The tick\\n * @return The depth of the tick\\n */\\n function getDepth(BookId id, Tick tick) external view returns (uint64);\\n\\n /**\\n * @notice Retrieves the highest tick for a given book ID\\n * @param id The book ID\\n * @return tick The highest tick\\n */\\n function getHighest(BookId id) external view returns (Tick tick);\\n\\n /**\\n * @notice Finds the maximum tick less than a specified tick in a book\\n * @dev Returns `Tick.wrap(type(int24).min)` if the specified tick is the lowest\\n * @param id The book ID\\n * @param tick The specified tick\\n * @return The next lower tick\\n */\\n function maxLessThan(BookId id, Tick tick) external view returns (Tick);\\n\\n /**\\n * @notice Checks if a book is opened\\n * @param id The book ID\\n * @return True if the book is opened, false otherwise\\n */\\n function isOpened(BookId id) external view returns (bool);\\n\\n /**\\n * @notice Checks if a book is empty\\n * @param id The book ID\\n * @return True if the book is empty, false otherwise\\n */\\n function isEmpty(BookId id) external view returns (bool);\\n\\n /**\\n * @notice Encodes a BookKey into a BookId\\n * @param key The BookKey to encode\\n * @return The encoded BookId\\n */\\n function encodeBookKey(BookKey calldata key) external pure returns (BookId);\\n\\n /**\\n * @notice Loads a value from a specific storage slot\\n * @param slot The storage slot\\n * @return The value in the slot\\n */\\n function load(bytes32 slot) external view returns (bytes32);\\n\\n /**\\n * @notice Loads a sequence of values starting from a specific slot\\n * @param startSlot The starting slot\\n * @param nSlot The number of slots to load\\n * @return The sequence of values\\n */\\n function load(bytes32 startSlot, uint256 nSlot) external view returns (bytes memory);\\n\\n /**\\n * @notice Opens a new book\\n * @param key The book key\\n * @param hookData The hook data\\n */\\n function open(BookKey calldata key, bytes calldata hookData) external;\\n\\n /**\\n * @notice Locks a book manager function\\n * @param locker The locker address\\n * @param data The lock data\\n * @return The lock return data\\n */\\n function lock(address locker, bytes calldata data) external returns (bytes memory);\\n\\n /**\\n * @notice This structure represents the parameters for making an order.\\n * @param key The book key for the order\\n * @param tick The tick for the order\\n * @param unit The unit for the order. Times key.unitSize to get actual bid amount.\\n * @param provider The provider for the order. The limit order service provider address to collect fees.\\n */\\n struct MakeParams {\\n BookKey key;\\n Tick tick;\\n uint64 unit;\\n address provider;\\n }\\n\\n /**\\n * @notice Make a limit order\\n * @param params The order parameters\\n * @param hookData The hook data\\n * @return id The order id. Returns 0 if the order is not settled\\n * @return quoteAmount The amount of quote currency to be paid\\n */\\n function make(MakeParams calldata params, bytes calldata hookData)\\n external\\n returns (OrderId id, uint256 quoteAmount);\\n\\n /**\\n * @notice This structure represents the parameters for taking orders in the specified tick.\\n * @param key The book key for the order\\n * @param tick The tick for the order\\n * @param maxUnit The max unit to take\\n */\\n struct TakeParams {\\n BookKey key;\\n Tick tick;\\n uint64 maxUnit;\\n }\\n\\n /**\\n * @notice Take a limit order at specific tick\\n * @param params The order parameters\\n * @param hookData The hook data\\n * @return quoteAmount The amount of quote currency to be received\\n * @return baseAmount The amount of base currency to be paid\\n */\\n function take(TakeParams calldata params, bytes calldata hookData)\\n external\\n returns (uint256 quoteAmount, uint256 baseAmount);\\n\\n /**\\n * @notice This structure represents the parameters for canceling an order.\\n * @param id The order id for the order\\n * @param toUnit The remaining open unit for the order after cancellation. Must not exceed the current open unit.\\n */\\n struct CancelParams {\\n OrderId id;\\n uint64 toUnit;\\n }\\n\\n /**\\n * @notice Cancel a limit order\\n * @param params The order parameters\\n * @param hookData The hook data\\n * @return canceledAmount The amount of quote currency canceled\\n */\\n function cancel(CancelParams calldata params, bytes calldata hookData) external returns (uint256 canceledAmount);\\n\\n /**\\n * @notice Claims an order\\n * @param id The order ID\\n * @param hookData The hook data\\n * @return claimedAmount The amount claimed\\n */\\n function claim(OrderId id, bytes calldata hookData) external returns (uint256 claimedAmount);\\n\\n /**\\n * @notice Collects fees from a provider\\n * @param recipient The recipient address\\n * @param currency The currency\\n * @return The collected amount\\n */\\n function collect(address recipient, Currency currency) external returns (uint256);\\n\\n /**\\n * @notice Withdraws a currency\\n * @param currency The currency\\n * @param to The recipient address\\n * @param amount The amount\\n */\\n function withdraw(Currency currency, address to, uint256 amount) external;\\n\\n /**\\n * @notice Settles a currency\\n * @param currency The currency\\n * @return The settled amount\\n */\\n function settle(Currency currency) external payable returns (uint256);\\n\\n /**\\n * @notice Whitelists a provider\\n * @param provider The provider address\\n */\\n function whitelist(address provider) external;\\n\\n /**\\n * @notice Delists a provider\\n * @param provider The provider address\\n */\\n function delist(address provider) external;\\n\\n /**\\n * @notice Sets the default provider\\n * @param newDefaultProvider The new default provider address\\n */\\n function setDefaultProvider(address newDefaultProvider) external;\\n}\\n\",\"keccak256\":\"0xda8dffc751ac3554033e084919f1e431eb2585c80e1e30b9a0198366a8607086\",\"license\":\"MIT\"},\"v2-core/interfaces/IERC721Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/**\\n * @title IERC721Permit\\n * @notice An interface for the ERC721 permit extension\\n */\\ninterface IERC721Permit is IERC721 {\\n error InvalidSignature();\\n error PermitExpired();\\n\\n /**\\n * @notice The EIP-712 typehash for the permit struct used by the contract\\n */\\n function PERMIT_TYPEHASH() external pure returns (bytes32);\\n\\n /**\\n * @notice The EIP-712 domain separator for this contract\\n */\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n\\n /**\\n * @notice Approve the spender to transfer the given tokenId\\n * @param spender The address to approve\\n * @param tokenId The tokenId to approve\\n * @param deadline The deadline for the signature\\n * @param v The recovery id of the signature\\n * @param r The r value of the signature\\n * @param s The s value of the signature\\n */\\n function permit(address spender, uint256 tokenId, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\\n\\n /**\\n * @notice Get the current nonce for a token\\n * @param tokenId The tokenId to get the nonce for\\n * @return The current nonce\\n */\\n function nonces(uint256 tokenId) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xd6baab4710fa674981395f428bd6550c4e288ac44a1a5d38c2a58fd67234d57e\",\"license\":\"MIT\"},\"v2-core/interfaces/IHooks.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.20;\\n\\nimport {IBookManager} from \\\"./IBookManager.sol\\\";\\nimport {OrderId} from \\\"../libraries/OrderId.sol\\\";\\n\\n/**\\n * @title IHooks\\n * @notice Interface for the hooks contract\\n */\\ninterface IHooks {\\n /**\\n * @notice Hook called before opening a new book\\n * @param sender The sender of the open transaction\\n * @param key The key of the book being opened\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function beforeOpen(address sender, IBookManager.BookKey calldata key, bytes calldata hookData)\\n external\\n returns (bytes4);\\n\\n /**\\n * @notice Hook called after opening a new book\\n * @param sender The sender of the open transaction\\n * @param key The key of the book being opened\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function afterOpen(address sender, IBookManager.BookKey calldata key, bytes calldata hookData)\\n external\\n returns (bytes4);\\n\\n /**\\n * @notice Hook called before making a new order\\n * @param sender The sender of the make transaction\\n * @param params The parameters of the make transaction\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function beforeMake(address sender, IBookManager.MakeParams calldata params, bytes calldata hookData)\\n external\\n returns (bytes4);\\n\\n /**\\n * @notice Hook called after making a new order\\n * @param sender The sender of the make transaction\\n * @param params The parameters of the make transaction\\n * @param orderId The id of the order that was made\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function afterMake(\\n address sender,\\n IBookManager.MakeParams calldata params,\\n OrderId orderId,\\n bytes calldata hookData\\n ) external returns (bytes4);\\n\\n /**\\n * @notice Hook called before taking an order\\n * @param sender The sender of the take transaction\\n * @param params The parameters of the take transaction\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function beforeTake(address sender, IBookManager.TakeParams calldata params, bytes calldata hookData)\\n external\\n returns (bytes4);\\n\\n /**\\n * @notice Hook called after taking an order\\n * @param sender The sender of the take transaction\\n * @param params The parameters of the take transaction\\n * @param takenUnit The unit that was taken\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function afterTake(\\n address sender,\\n IBookManager.TakeParams calldata params,\\n uint64 takenUnit,\\n bytes calldata hookData\\n ) external returns (bytes4);\\n\\n /**\\n * @notice Hook called before canceling an order\\n * @param sender The sender of the cancel transaction\\n * @param params The parameters of the cancel transaction\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function beforeCancel(address sender, IBookManager.CancelParams calldata params, bytes calldata hookData)\\n external\\n returns (bytes4);\\n\\n /**\\n * @notice Hook called after canceling an order\\n * @param sender The sender of the cancel transaction\\n * @param params The parameters of the cancel transaction\\n * @param canceledUnit The unit that was canceled\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function afterCancel(\\n address sender,\\n IBookManager.CancelParams calldata params,\\n uint64 canceledUnit,\\n bytes calldata hookData\\n ) external returns (bytes4);\\n\\n /**\\n * @notice Hook called before claiming an order\\n * @param sender The sender of the claim transaction\\n * @param orderId The id of the order being claimed\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function beforeClaim(address sender, OrderId orderId, bytes calldata hookData) external returns (bytes4);\\n\\n /**\\n * @notice Hook called after claiming an order\\n * @param sender The sender of the claim transaction\\n * @param orderId The id of the order being claimed\\n * @param claimedUnit The unit that was claimed\\n * @param hookData The data passed to the hook\\n * @return Returns the function selector if the hook is successful\\n */\\n function afterClaim(address sender, OrderId orderId, uint64 claimedUnit, bytes calldata hookData)\\n external\\n returns (bytes4);\\n}\\n\",\"keccak256\":\"0xbff95e07debd7d51cb3aa79172fd3c31efb57cea1c03d21b5740a565198d8343\",\"license\":\"MIT\"},\"v2-core/interfaces/ILocker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ILocker\\n * @notice Interface for the locker contract\\n */\\ninterface ILocker {\\n /**\\n * @notice Called by the book manager on `msg.sender` when a lock is acquired\\n * @param data The data that was passed to the call to lock\\n * @return Any data that you want to be returned from the lock call\\n */\\n function lockAcquired(address lockCaller, bytes calldata data) external returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x664833ea7804ad5cbbe89f5b36169c6a2c19ef577c1dfb9418ddea290ed19106\",\"license\":\"MIT\"},\"v2-core/libraries/BookId.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.20;\\n\\nimport {IBookManager} from \\\"../interfaces/IBookManager.sol\\\";\\n\\ntype BookId is uint192;\\n\\nlibrary BookIdLibrary {\\n function toId(IBookManager.BookKey memory bookKey) internal pure returns (BookId id) {\\n bytes32 hash = keccak256(abi.encode(bookKey));\\n assembly {\\n id := and(hash, 0xffffffffffffffffffffffffffffffffffffffffffffffff)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x60f9ed99dfb9a5ce14c29359a5ad8b43de0c756e44b2e5f581e8ea6db7cacbeb\",\"license\":\"GPL-2.0-or-later\"},\"v2-core/libraries/Currency.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ntype Currency is address;\\n\\n/// @title CurrencyLibrary\\n/// @dev This library allows for transferring and holding native tokens and ERC20 tokens\\nlibrary CurrencyLibrary {\\n using CurrencyLibrary for Currency;\\n\\n /// @notice Thrown when a native transfer fails\\n error NativeTransferFailed();\\n\\n /// @notice Thrown when an ERC20 transfer fails\\n error ERC20TransferFailed();\\n\\n Currency public constant NATIVE = Currency.wrap(address(0));\\n\\n function transfer(Currency currency, address to, uint256 amount) internal {\\n // implementation from\\n // https://github.com/transmissions11/solmate/blob/e8f96f25d48fe702117ce76c79228ca4f20206cb/src/utils/SafeTransferLib.sol\\n\\n bool success;\\n if (currency.isNative()) {\\n assembly {\\n // Transfer the ETH and store if it succeeded or not.\\n success := call(gas(), to, amount, 0, 0, 0, 0)\\n }\\n\\n if (!success) revert NativeTransferFailed();\\n } else {\\n assembly {\\n // Get a pointer to some free memory.\\n let freeMemoryPointer := mload(0x40)\\n\\n // Write the abi-encoded calldata into memory, beginning with the function selector.\\n mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\\n mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \\\"to\\\" argument.\\n mstore(add(freeMemoryPointer, 36), amount) // Append the \\\"amount\\\" argument. Masking not required as it's a full 32 byte type.\\n\\n success :=\\n and(\\n // Set success to whether the call reverted, if not we check it either\\n // returned exactly 1 (can't just be non-zero data), or had no return data.\\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\\n // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\\n // Counterintuitively, this call must be positioned second to the or() call in the\\n // surrounding and() call or else returndatasize() will be zero during the computation.\\n call(gas(), currency, 0, freeMemoryPointer, 68, 0, 32)\\n )\\n }\\n\\n if (!success) revert ERC20TransferFailed();\\n }\\n }\\n\\n function balanceOfSelf(Currency currency) internal view returns (uint256) {\\n if (currency.isNative()) return address(this).balance;\\n else return IERC20(Currency.unwrap(currency)).balanceOf(address(this));\\n }\\n\\n function equals(Currency currency, Currency other) internal pure returns (bool) {\\n return Currency.unwrap(currency) == Currency.unwrap(other);\\n }\\n\\n function isNative(Currency currency) internal pure returns (bool) {\\n return Currency.unwrap(currency) == Currency.unwrap(NATIVE);\\n }\\n\\n function toId(Currency currency) internal pure returns (uint256) {\\n return uint160(Currency.unwrap(currency));\\n }\\n\\n function fromId(uint256 id) internal pure returns (Currency) {\\n return Currency.wrap(address(uint160(id)));\\n }\\n}\\n\",\"keccak256\":\"0xf04f76015a51981ad0f84fd3ebb0a4eb6c31685604c22584669915aa8dd7ac54\",\"license\":\"GPL-2.0-or-later\"},\"v2-core/libraries/FeePolicy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"./Math.sol\\\";\\n\\ntype FeePolicy is uint24;\\n\\nlibrary FeePolicyLibrary {\\n uint256 internal constant RATE_PRECISION = 10 ** 6;\\n int256 internal constant MAX_FEE_RATE = 500000;\\n int256 internal constant MIN_FEE_RATE = -500000;\\n\\n uint256 internal constant RATE_MASK = 0x7fffff; // 23 bits\\n\\n error InvalidFeePolicy();\\n\\n function encode(bool usesQuote_, int24 rate_) internal pure returns (FeePolicy feePolicy) {\\n if (rate_ > MAX_FEE_RATE || rate_ < MIN_FEE_RATE) {\\n revert InvalidFeePolicy();\\n }\\n\\n uint256 mask = usesQuote_ ? 1 << 23 : 0;\\n assembly {\\n feePolicy := or(mask, add(and(rate_, 0xffffff), MAX_FEE_RATE))\\n }\\n }\\n\\n function isValid(FeePolicy self) internal pure returns (bool) {\\n int24 r = rate(self);\\n\\n return !(r > MAX_FEE_RATE || r < MIN_FEE_RATE);\\n }\\n\\n function usesQuote(FeePolicy self) internal pure returns (bool f) {\\n assembly {\\n f := shr(23, self)\\n }\\n }\\n\\n function rate(FeePolicy self) internal pure returns (int24 r) {\\n assembly {\\n r := sub(and(self, RATE_MASK), MAX_FEE_RATE)\\n }\\n }\\n\\n function calculateFee(FeePolicy self, uint256 amount, bool reverseRounding) internal pure returns (int256 fee) {\\n int24 r = rate(self);\\n\\n bool positive = r > 0;\\n uint256 absRate;\\n unchecked {\\n absRate = uint256(uint24(positive ? r : -r));\\n }\\n // @dev absFee must be less than type(int256).max\\n uint256 absFee = Math.divide(amount * absRate, RATE_PRECISION, reverseRounding ? !positive : positive);\\n fee = positive ? int256(absFee) : -int256(absFee);\\n }\\n\\n function calculateOriginalAmount(FeePolicy self, uint256 amount, bool reverseFee)\\n internal\\n pure\\n returns (uint256 originalAmount)\\n {\\n int24 r = rate(self);\\n\\n bool positive = r > 0;\\n uint256 divider;\\n assembly {\\n if reverseFee { r := sub(0, r) }\\n divider := add(RATE_PRECISION, r)\\n }\\n originalAmount = Math.divide(amount * RATE_PRECISION, divider, positive);\\n }\\n}\\n\",\"keccak256\":\"0x91f98ffef9d8a0bb460bcbc31d10820d9a1bee9bbf3df04eef23ca2937a4a26a\",\"license\":\"GPL-2.0-or-later\"},\"v2-core/libraries/Math.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.0;\\n\\nlibrary Math {\\n function divide(uint256 a, uint256 b, bool roundingUp) internal pure returns (uint256 ret) {\\n // In the OrderBook contract code, b is never zero.\\n assembly {\\n ret := add(div(a, b), and(gt(mod(a, b), 0), roundingUp))\\n }\\n }\\n\\n /// @dev Returns `ln(x)`, denominated in `WAD`.\\n /// Credit to Remco Bloemen under MIT license: https://2\\u03c0.com/22/exp-ln\\n function lnWad(int256 x) internal pure returns (int256 r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n // We want to convert `x` from `10**18` fixed point to `2**96` fixed point.\\n // We do this by multiplying by `2**96 / 10**18`. But since\\n // `ln(x * C) = ln(x) + ln(C)`, we can simply do nothing here\\n // and add `ln(2**96 / 10**18)` at the end.\\n\\n // Compute `k = log2(x) - 96`, `r = 159 - k = 255 - log2(x) = 255 ^ log2(x)`.\\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\\n r := or(r, shl(3, lt(0xff, shr(r, x))))\\n // We place the check here for more optimal stack operations.\\n if iszero(sgt(x, 0)) {\\n mstore(0x00, 0x1615e638) // `LnWadUndefined()`.\\n revert(0x1c, 0x04)\\n }\\n // forgefmt: disable-next-item\\n r := xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),\\n 0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff))\\n\\n // Reduce range of x to (1, 2) * 2**96\\n // ln(2^k * x) = k * ln(2) + ln(x)\\n x := shr(159, shl(r, x))\\n\\n // Evaluate using a (8, 8)-term rational approximation.\\n // `p` is made monic, we will multiply by a scale factor later.\\n // forgefmt: disable-next-item\\n let p := sub( // This heavily nested expression is to avoid stack-too-deep for via-ir.\\n sar(96, mul(add(43456485725739037958740375743393,\\n sar(96, mul(add(24828157081833163892658089445524,\\n sar(96, mul(add(3273285459638523848632254066296,\\n x), x))), x))), x)), 11111509109440967052023855526967)\\n p := sub(sar(96, mul(p, x)), 45023709667254063763336534515857)\\n p := sub(sar(96, mul(p, x)), 14706773417378608786704636184526)\\n p := sub(mul(p, x), shl(96, 795164235651350426258249787498))\\n // We leave `p` in `2**192` basis so we don't need to scale it back up for the division.\\n\\n // `q` is monic by convention.\\n let q := add(5573035233440673466300451813936, x)\\n q := add(71694874799317883764090561454958, sar(96, mul(x, q)))\\n q := add(283447036172924575727196451306956, sar(96, mul(x, q)))\\n q := add(401686690394027663651624208769553, sar(96, mul(x, q)))\\n q := add(204048457590392012362485061816622, sar(96, mul(x, q)))\\n q := add(31853899698501571402653359427138, sar(96, mul(x, q)))\\n q := add(909429971244387300277376558375, sar(96, mul(x, q)))\\n\\n // `p / q` is in the range `(0, 0.125) * 2**96`.\\n\\n // Finalization, we need to:\\n // - Multiply by the scale factor `s = 5.549\\u2026`.\\n // - Add `ln(2**96 / 10**18)`.\\n // - Add `k * ln(2)`.\\n // - Multiply by `10**18 / 2**96 = 5**18 >> 78`.\\n\\n // The q polynomial is known not to have zeros in the domain.\\n // No scaling required because p is already `2**96` too large.\\n p := sdiv(p, q)\\n // Multiply by the scaling factor: `s * 5**18 * 2**96`, base is now `5**18 * 2**192`.\\n p := mul(1677202110996718588342820967067443963516166, p)\\n // Add `ln(2) * k * 5**18 * 2**192`.\\n // forgefmt: disable-next-item\\n p := add(mul(16597577552685614221487285958193947469193820559219878177908093499208371, sub(159, r)), p)\\n // Base conversion: mul `2**96 / (5**18 * 2**192)`.\\n r := sdiv(p, 302231454903657293676544000000000000000000)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb2dc502dd66a9e36e6c4bb8c4fb3d21120f9f0ff7a934dcfe21ec820cac72275\",\"license\":\"GPL-2.0-or-later\"},\"v2-core/libraries/OrderId.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.0;\\n\\nimport {Tick} from \\\"./Tick.sol\\\";\\nimport {BookId} from \\\"./BookId.sol\\\";\\n\\ntype OrderId is uint256;\\n\\nlibrary OrderIdLibrary {\\n /**\\n * @dev Encode the order id.\\n * @param bookId The book id.\\n * @param tick The tick.\\n * @param index The index.\\n * @return id The order id.\\n */\\n function encode(BookId bookId, Tick tick, uint40 index) internal pure returns (OrderId id) {\\n // @dev If we just use tick at the assembly code, the code will convert tick into bytes32.\\n // e.g. When index == -2, the shifted value( shl(40, tick) ) will be\\n // 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000 instead of 0xfffffffe0000000000\\n // Therefore, we have to safely cast tick into uint256 first.\\n uint256 _tick = uint256(uint24(Tick.unwrap(tick)));\\n assembly {\\n id := add(index, add(shl(40, _tick), shl(64, bookId)))\\n }\\n }\\n\\n function decode(OrderId id) internal pure returns (BookId bookId, Tick tick, uint40 index) {\\n assembly {\\n bookId := shr(64, id)\\n tick := and(shr(40, id), 0xffffff)\\n index := and(id, 0xffffffffff)\\n }\\n }\\n\\n function getBookId(OrderId id) internal pure returns (BookId bookId) {\\n assembly {\\n bookId := shr(64, id)\\n }\\n }\\n\\n function getTick(OrderId id) internal pure returns (Tick tick) {\\n assembly {\\n tick := and(shr(40, id), 0xffffff)\\n }\\n }\\n\\n function getIndex(OrderId id) internal pure returns (uint40 index) {\\n assembly {\\n index := and(id, 0xffffffffff)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x78c384badc4971d774987c6f5bce9d578712c7469688735b3c1eafaf2e748fe6\",\"license\":\"GPL-2.0-or-later\"},\"v2-core/libraries/Tick.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-2.0-or-later\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"./Math.sol\\\";\\n\\ntype Tick is int24;\\n\\nlibrary TickLibrary {\\n using Math for *;\\n using TickLibrary for Tick;\\n\\n error InvalidTick();\\n error InvalidPrice();\\n error TickOverflow();\\n\\n int24 internal constant MAX_TICK = 2 ** 19 - 1;\\n int24 internal constant MIN_TICK = -MAX_TICK;\\n\\n uint256 internal constant MIN_PRICE = 1350587;\\n uint256 internal constant MAX_PRICE = 4647684107270898330752324302845848816923571339324334;\\n\\n uint256 private constant _R0 = 0xfff97272373d413259a46990;\\n uint256 private constant _R1 = 0xfff2e50f5f656932ef12357c;\\n uint256 private constant _R2 = 0xffe5caca7e10e4e61c3624ea;\\n uint256 private constant _R3 = 0xffcb9843d60f6159c9db5883;\\n uint256 private constant _R4 = 0xff973b41fa98c081472e6896;\\n uint256 private constant _R5 = 0xff2ea16466c96a3843ec78b3;\\n uint256 private constant _R6 = 0xfe5dee046a99a2a811c461f1;\\n uint256 private constant _R7 = 0xfcbe86c7900a88aedcffc83b;\\n uint256 private constant _R8 = 0xf987a7253ac413176f2b074c;\\n uint256 private constant _R9 = 0xf3392b0822b70005940c7a39;\\n uint256 private constant _R10 = 0xe7159475a2c29b7443b29c7f;\\n uint256 private constant _R11 = 0xd097f3bdfd2022b8845ad8f7;\\n uint256 private constant _R12 = 0xa9f746462d870fdf8a65dc1f;\\n uint256 private constant _R13 = 0x70d869a156d2a1b890bb3df6;\\n uint256 private constant _R14 = 0x31be135f97d08fd981231505;\\n uint256 private constant _R15 = 0x9aa508b5b7a84e1c677de54;\\n uint256 private constant _R16 = 0x5d6af8dedb81196699c329;\\n uint256 private constant _R17 = 0x2216e584f5fa1ea92604;\\n uint256 private constant _R18 = 0x48a170391f7dc42;\\n uint256 private constant _R19 = 0x149b34;\\n\\n function validateTick(Tick tick) internal pure {\\n if (Tick.unwrap(tick) > MAX_TICK || Tick.unwrap(tick) < MIN_TICK) revert InvalidTick();\\n }\\n\\n modifier validatePrice(uint256 price) {\\n if (price > MAX_PRICE || price < MIN_PRICE) revert InvalidPrice();\\n _;\\n }\\n\\n function fromPrice(uint256 price) internal pure validatePrice(price) returns (Tick) {\\n unchecked {\\n int24 tick = int24((int256(price).lnWad() * 42951820407860) / 2 ** 128);\\n if (toPrice(Tick.wrap(tick)) > price) return Tick.wrap(tick - 1);\\n return Tick.wrap(tick);\\n }\\n }\\n\\n function toPrice(Tick tick) internal pure returns (uint256 price) {\\n validateTick(tick);\\n int24 tickValue = Tick.unwrap(tick);\\n uint256 absTick = uint24(tickValue < 0 ? -tickValue : tickValue);\\n\\n unchecked {\\n if (absTick & 0x1 != 0) price = _R0;\\n else price = 1 << 96;\\n if (absTick & 0x2 != 0) price = (price * _R1) >> 96;\\n if (absTick & 0x4 != 0) price = (price * _R2) >> 96;\\n if (absTick & 0x8 != 0) price = (price * _R3) >> 96;\\n if (absTick & 0x10 != 0) price = (price * _R4) >> 96;\\n if (absTick & 0x20 != 0) price = (price * _R5) >> 96;\\n if (absTick & 0x40 != 0) price = (price * _R6) >> 96;\\n if (absTick & 0x80 != 0) price = (price * _R7) >> 96;\\n if (absTick & 0x100 != 0) price = (price * _R8) >> 96;\\n if (absTick & 0x200 != 0) price = (price * _R9) >> 96;\\n if (absTick & 0x400 != 0) price = (price * _R10) >> 96;\\n if (absTick & 0x800 != 0) price = (price * _R11) >> 96;\\n if (absTick & 0x1000 != 0) price = (price * _R12) >> 96;\\n if (absTick & 0x2000 != 0) price = (price * _R13) >> 96;\\n if (absTick & 0x4000 != 0) price = (price * _R14) >> 96;\\n if (absTick & 0x8000 != 0) price = (price * _R15) >> 96;\\n if (absTick & 0x10000 != 0) price = (price * _R16) >> 96;\\n if (absTick & 0x20000 != 0) price = (price * _R17) >> 96;\\n if (absTick & 0x40000 != 0) price = (price * _R18) >> 96;\\n }\\n if (tickValue > 0) price = 0x1000000000000000000000000000000000000000000000000 / price;\\n }\\n\\n function gt(Tick a, Tick b) internal pure returns (bool) {\\n return Tick.unwrap(a) > Tick.unwrap(b);\\n }\\n\\n function baseToQuote(Tick tick, uint256 base, bool roundingUp) internal pure returns (uint256) {\\n return Math.divide((base * tick.toPrice()), 1 << 96, roundingUp);\\n }\\n\\n function quoteToBase(Tick tick, uint256 quote, bool roundingUp) internal pure returns (uint256) {\\n // @dev quote = unit(uint64) * unitSize(uint64) < 2^96\\n // We don't need to check overflow here\\n return Math.divide(quote << 96, tick.toPrice(), roundingUp);\\n }\\n}\\n\",\"keccak256\":\"0xffbe19efd2b2e4e1eee3ed15c9363f5c45d70a6058b0b85ec9199e34de3b6b9b\",\"license\":\"GPL-2.0-or-later\"}},\"version\":1}", + "bytecode": "0x60a060405234801561000f575f80fd5b50604051611f16380380611f1683398101604081905261002e916100fe565b806001600160a01b03811661005c57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b61006581610078565b50506001600160a01b031660805261012f565b600180546001600160a01b031916905561009181610094565b50565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146100f9575f80fd5b919050565b5f806040838503121561010f575f80fd5b610118836100e3565b9150610126602084016100e3565b90509250929050565b608051611d826101945f395f818161014c015281816102ad0152818161037e015281816104460152818161052301528181610606015281816108c00152818161097101528181610a73015281816112ce0152818161135b01526113b80152611d825ff3fe6080604052600436106100bb575f3560e01c80636d70f7ae116100715780638da5cb5b1161004c5780638da5cb5b1461020b578063e30c397814610227578063f2fde38b14610244575f80fd5b80636d70f7ae146101a5578063715018a6146101e357806379ba5097146101f7575f80fd5b80633ccdbb28116100a15780633ccdbb281461011c5780633f322bc91461013b578063558a729714610186575f80fd5b806313ac61a4146100c657806315c7afb4146100e7575f80fd5b366100c257005b5f80fd5b3480156100d1575f80fd5b506100e56100e0366004611689565b610263565b005b3480156100f2575f80fd5b50610106610101366004611780565b610369565b604051610113919061183b565b60405180910390f35b348015610127575f80fd5b506100e5610136366004611854565b610b96565b348015610146575f80fd5b5061016e7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610113565b348015610191575f80fd5b506100e56101a03660046118a0565b610bb7565b3480156101b0575f80fd5b506101d36101bf3660046118d7565b60026020525f908152604090205460ff1681565b6040519015158152602001610113565b3480156101ee575f80fd5b506100e5610c1d565b348015610202575f80fd5b506100e5610c30565b348015610216575f80fd5b505f546001600160a01b031661016e565b348015610232575f80fd5b506001546001600160a01b031661016e565b34801561024f575f80fd5b506100e561025e3660046118d7565b610c79565b335f9081526002602052604090205460ff166102ab576040517f7c214f0400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639ca179983033878787876040516020016102f49594939291906118f2565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161032092919061194d565b5f604051808303815f875af115801561033b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261036291908101906119bb565b5050505050565b6060610373610cf6565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415806103b457506001600160a01b0383163014155b156103eb576040517fc0185c6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805f8480602001905181019061040291906119ed565b6040517f9b22917d0000000000000000000000000000000000000000000000000000000081526001600160c01b038416600482015290985092955090935091505f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639b22917d9060240160c060405180830381865afa158015610493573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104b79190611a7e565b90505f8060606104db84604001516001600160a01b03166001600160a01b03161590565b156105ea5760408481015190517fd9caed120000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201523060248201527f000000000000000000000000000000000000000000000000000000000000000090911680316044830181905294509063d9caed12906064015f604051808303815f87803b158015610571575f80fd5b505af1158015610583573d5f803e3d5ffd5b50505050846001600160a01b0316838a6040516105a09190611b2c565b5f6040518083038185875af1925050503d805f81146105da576040519150601f19603f3d011682016040523d82523d5f602084013e6105df565b606091505b5090925090506107bc565b60408481015190516370a0823160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528216906370a0823190602401602060405180830381865afa158015610653573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106779190611b42565b60405163095ea7b360e01b81526001600160a01b038881166004830152602482018390529195509082169063095ea7b3906044016020604051808303815f875af11580156106c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106eb9190611b59565b50856001600160a01b03168a6040516107049190611b2c565b5f604051808303815f865af19150503d805f811461073d576040519150601f19603f3d011682016040523d82523d5f602084013e610742565b606091505b5060405163095ea7b360e01b81526001600160a01b0389811660048301525f60248301529295509093509082169063095ea7b3906044016020604051808303815f875af1158015610795573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107b99190611b59565b50505b816107c5575f80fd5b5f6107dc85604001516001600160a01b0316610d75565b6107e69085611b88565b90505f6107fe865f01516001600160a01b0316610d75565b90505f806108158860a0015162ffffff1660171c90565b156108595760a088015161082f9062ffffff16855f610df6565b61083885610e76565b6108429190611b9b565b935061085283606086901b611bc2565b905061087f565b60a088015161086e9062ffffff16845f610ed8565b61087c90606086901b611bc2565b90505b828210801561093357506040517ffcc8fc9b0000000000000000000000000000000000000000000000000000000081526001600160c01b038b1660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063fcc8fc9b90602401602060405180830381865afa15801561090d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109319190611b59565b155b15610b51576040517fcdc92f2d0000000000000000000000000000000000000000000000000000000081526001600160c01b038b1660048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063cdc92f2d90602401602060405180830381865afa1580156109be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109e29190611be1565b90506109f08160020b610f2d565b82106109fc5750610b51565b5f610a108a60a0015162ffffff1660171c90565b15610a1e5750828403610a38565b60a08a0151610a359062ffffff168587035f610ed8565b90505b60208a015167ffffffffffffffff16610a56600284900b835f6111f5565b610a609190611bc2565b9050805f03610a70575050610b51565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633b9500b060405180606001604052808e81526020018660020b8152602001610ac38661123f565b67ffffffffffffffff168152506040518263ffffffff1660e01b8152600401610aec9190611c01565b60408051808303815f875af1158015610b07573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b2b9190611caa565b915050805f03610b3d57505050610b51565b610b478186611ccc565b945050505061087f565b610b5f8b896040015161128e565b610b6c8b895f015161128e565b60405180602001604052805f8152509b505050505050505050505050610b9061144a565b92915050565b610b9e61146f565b610bb26001600160a01b038416828461149b565b505050565b610bbf61146f565b6001600160a01b0382165f81815260026020908152604091829020805460ff191685151590811790915591519182527f1618a22a3b00b9ac70fd5a82f1f5cdd8cb272bd0f1b740ddf7c26ab05881dd5b910160405180910390a25050565b610c2561146f565b610c2e5f611583565b565b60015433906001600160a01b03168114610c6d5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b610c7681611583565b50565b610c8161146f565b600180546001600160a01b03831673ffffffffffffffffffffffffffffffffffffffff199091168117909155610cbe5f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45c15610d4f576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60017f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45d565b5f6001600160a01b038216610d8b575047919050565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610dcd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b909190611b42565b919050565b5f6207a11f19627fffff851601600281900b82128281610e1857825f03610e1a565b825b62ffffff1690505f610e53610e2f8389611cdf565b620f424088610e45578581830615151691040190565b808206151586151691040190565b905082610e6857610e6381611cf6565b610e6a565b805b98975050505050505050565b5f7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821115610ed4576040517f24775e0600000000000000000000000000000000000000000000000000000000815260048101839052602401610c64565b5090565b5f6207a11f19627fffff851601600281900b8212828415610ef957825f0392505b82620f4240019050610f22620f424087610f139190611cdf565b82810615158416908390040190565b979650505050505050565b5f610f37826115a9565b815f600282900b8113610f4a5781610f53565b610f5382611d2c565b62ffffff8116915060011615610f77576bfff97272373d413259a469909250610f88565b6c0100000000000000000000000092505b6002811615610fa75760606bfff2e50f5f656932ef12357c8402901c92505b6004811615610fc65760606bffe5caca7e10e4e61c3624ea8402901c92505b6008811615610fe55760606bffcb9843d60f6159c9db58838402901c92505b60108116156110045760606bff973b41fa98c081472e68968402901c92505b60208116156110235760606bff2ea16466c96a3843ec78b38402901c92505b60408116156110425760606bfe5dee046a99a2a811c461f18402901c92505b60808116156110615760606bfcbe86c7900a88aedcffc83b8402901c92505b6101008116156110815760606bf987a7253ac413176f2b074c8402901c92505b6102008116156110a15760606bf3392b0822b70005940c7a398402901c92505b6104008116156110c15760606be7159475a2c29b7443b29c7f8402901c92505b6108008116156110e15760606bd097f3bdfd2022b8845ad8f78402901c92505b6110008116156111015760606ba9f746462d870fdf8a65dc1f8402901c92505b6120008116156111215760606b70d869a156d2a1b890bb3df68402901c92505b6140008116156111415760606b31be135f97d08fd9812315058402901c92505b6180008116156111615760606b09aa508b5b7a84e1c677de548402901c92505b620100008116156111815760606a5d6af8dedb81196699c3298402901c92505b620200008116156111a0576060692216e584f5fa1ea926048402901c92505b620400008116156111bd57606067048a170391f7dc428402901c92505b5f8260020b13156111ee576111eb837801000000000000000000000000000000000000000000000000611bc2565b92505b5050919050565b5f6112376112058560020b610f2d565b61120f9085611cdf565b6bffffffffffffffffffffffff8116151584166c010000000000000000000000009091040190565b949350505050565b5f67ffffffffffffffff821115610ed457604080517f6dfcc650000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610c64565b6040517f9611cf6c0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0382811660248301525f917f000000000000000000000000000000000000000000000000000000000000000090911690639611cf6c90604401602060405180830381865afa158015611315573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113399190611b42565b61134290611cf6565b90505f811315611380576113806001600160a01b0383167f00000000000000000000000000000000000000000000000000000000000000008361149b565b6040517f6a256b290000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301527f00000000000000000000000000000000000000000000000000000000000000001690636a256b29906024016020604051808303815f875af11580156113fe573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114229190611b42565b50610bb283611439846001600160a01b0316610d75565b6001600160a01b038516919061149b565b5f7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45d565b5f546001600160a01b03163314610c2e5760405163118cdaa760e01b8152336004820152602401610c64565b5f6001600160a01b0384166114f0575f805f8085875af19050806114eb576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61157d565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f51141617169150508061157d576040517ff27f64e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6001805473ffffffffffffffffffffffffffffffffffffffff19169055610c7681611605565b6207ffff600282900b13806115ce57506115c56207ffff611d2c565b60020b8160020b125b15610c76576040517fce8ef7fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160c01b0381168114610c76575f80fd5b6001600160a01b0381168114610c76575f80fd5b5f805f806060858703121561169c575f80fd5b84356116a781611661565b935060208501356116b781611675565b9250604085013567ffffffffffffffff808211156116d3575f80fd5b818701915087601f8301126116e6575f80fd5b8135818111156116f4575f80fd5b886020828501011115611705575f80fd5b95989497505060200194505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561175157611751611714565b604052919050565b5f67ffffffffffffffff82111561177257611772611714565b50601f01601f191660200190565b5f8060408385031215611791575f80fd5b823561179c81611675565b9150602083013567ffffffffffffffff8111156117b7575f80fd5b8301601f810185136117c7575f80fd5b80356117da6117d582611759565b611728565b8181528660208385010111156117ee575f80fd5b816020840160208301375f602083830101528093505050509250929050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61184d602083018461180d565b9392505050565b5f805f60608486031215611866575f80fd5b833561187181611675565b925060208401359150604084013561188881611675565b809150509250925092565b8015158114610c76575f80fd5b5f80604083850312156118b1575f80fd5b82356118bc81611675565b915060208301356118cc81611893565b809150509250929050565b5f602082840312156118e7575f80fd5b813561184d81611675565b5f6001600160a01b0380881683526001600160c01b038716602084015280861660408401525060806060830152826080830152828460a08401375f60a0848401015260a0601f19601f85011683010190509695505050505050565b6001600160a01b0383168152604060208201525f611237604083018461180d565b5f82601f83011261197d575f80fd5b815161198b6117d582611759565b81815284602083860101111561199f575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f602082840312156119cb575f80fd5b815167ffffffffffffffff8111156119e1575f80fd5b6112378482850161196e565b5f805f8060808587031215611a00575f80fd5b8451611a0b81611675565b6020860151909450611a1c81611661565b6040860151909350611a2d81611675565b606086015190925067ffffffffffffffff811115611a49575f80fd5b611a558782880161196e565b91505092959194509250565b805162ffffff81168114610df1575f80fd5b8051610df181611675565b5f60c08284031215611a8e575f80fd5b60405160c0810167ffffffffffffffff8282108183111715611ab257611ab2611714565b8160405284519150611ac382611675565b9082526020840151908082168214611ad9575f80fd5b5060208201526040830151611aed81611675565b6040820152611afe60608401611a61565b6060820152611b0f60808401611a73565b6080820152611b2060a08401611a61565b60a08201529392505050565b5f82518060208501845e5f920191825250919050565b5f60208284031215611b52575f80fd5b5051919050565b5f60208284031215611b69575f80fd5b815161184d81611893565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610b9057610b90611b74565b8082018281125f831280158216821582161715611bba57611bba611b74565b505092915050565b5f82611bdc57634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215611bf1575f80fd5b81518060020b811461184d575f80fd5b5f61012083516001600160a01b0380825116855267ffffffffffffffff602083015116602086015280604083015116604086015262ffffff60608301511660608601528060808301511660808601525060a08101519050611c6960a085018262ffffff169052565b506020840151611c7e60c085018260020b9052565b50604084015167ffffffffffffffff1660e084015261010083018190525f818401908152602001611237565b5f8060408385031215611cbb575f80fd5b505080516020909101519092909150565b80820180821115610b9057610b90611b74565b8082028115828204841417610b9057610b90611b74565b5f7f80000000000000000000000000000000000000000000000000000000000000008203611d2657611d26611b74565b505f0390565b5f8160020b627fffff198103611d4457611d44611b74565b5f039291505056fea26469706673582212203d102bafa2cceb63221cf5fed2d181aa828f35df49d2c386bc2aab4b700b2a3064736f6c63430008190033", + "deployedBytecode": "0x6080604052600436106100bb575f3560e01c80636d70f7ae116100715780638da5cb5b1161004c5780638da5cb5b1461020b578063e30c397814610227578063f2fde38b14610244575f80fd5b80636d70f7ae146101a5578063715018a6146101e357806379ba5097146101f7575f80fd5b80633ccdbb28116100a15780633ccdbb281461011c5780633f322bc91461013b578063558a729714610186575f80fd5b806313ac61a4146100c657806315c7afb4146100e7575f80fd5b366100c257005b5f80fd5b3480156100d1575f80fd5b506100e56100e0366004611689565b610263565b005b3480156100f2575f80fd5b50610106610101366004611780565b610369565b604051610113919061183b565b60405180910390f35b348015610127575f80fd5b506100e5610136366004611854565b610b96565b348015610146575f80fd5b5061016e7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610113565b348015610191575f80fd5b506100e56101a03660046118a0565b610bb7565b3480156101b0575f80fd5b506101d36101bf3660046118d7565b60026020525f908152604090205460ff1681565b6040519015158152602001610113565b3480156101ee575f80fd5b506100e5610c1d565b348015610202575f80fd5b506100e5610c30565b348015610216575f80fd5b505f546001600160a01b031661016e565b348015610232575f80fd5b506001546001600160a01b031661016e565b34801561024f575f80fd5b506100e561025e3660046118d7565b610c79565b335f9081526002602052604090205460ff166102ab576040517f7c214f0400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639ca179983033878787876040516020016102f49594939291906118f2565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161032092919061194d565b5f604051808303815f875af115801561033b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261036291908101906119bb565b5050505050565b6060610373610cf6565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415806103b457506001600160a01b0383163014155b156103eb576040517fc0185c6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805f8480602001905181019061040291906119ed565b6040517f9b22917d0000000000000000000000000000000000000000000000000000000081526001600160c01b038416600482015290985092955090935091505f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639b22917d9060240160c060405180830381865afa158015610493573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104b79190611a7e565b90505f8060606104db84604001516001600160a01b03166001600160a01b03161590565b156105ea5760408481015190517fd9caed120000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201523060248201527f000000000000000000000000000000000000000000000000000000000000000090911680316044830181905294509063d9caed12906064015f604051808303815f87803b158015610571575f80fd5b505af1158015610583573d5f803e3d5ffd5b50505050846001600160a01b0316838a6040516105a09190611b2c565b5f6040518083038185875af1925050503d805f81146105da576040519150601f19603f3d011682016040523d82523d5f602084013e6105df565b606091505b5090925090506107bc565b60408481015190516370a0823160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528216906370a0823190602401602060405180830381865afa158015610653573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106779190611b42565b60405163095ea7b360e01b81526001600160a01b038881166004830152602482018390529195509082169063095ea7b3906044016020604051808303815f875af11580156106c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106eb9190611b59565b50856001600160a01b03168a6040516107049190611b2c565b5f604051808303815f865af19150503d805f811461073d576040519150601f19603f3d011682016040523d82523d5f602084013e610742565b606091505b5060405163095ea7b360e01b81526001600160a01b0389811660048301525f60248301529295509093509082169063095ea7b3906044016020604051808303815f875af1158015610795573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107b99190611b59565b50505b816107c5575f80fd5b5f6107dc85604001516001600160a01b0316610d75565b6107e69085611b88565b90505f6107fe865f01516001600160a01b0316610d75565b90505f806108158860a0015162ffffff1660171c90565b156108595760a088015161082f9062ffffff16855f610df6565b61083885610e76565b6108429190611b9b565b935061085283606086901b611bc2565b905061087f565b60a088015161086e9062ffffff16845f610ed8565b61087c90606086901b611bc2565b90505b828210801561093357506040517ffcc8fc9b0000000000000000000000000000000000000000000000000000000081526001600160c01b038b1660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063fcc8fc9b90602401602060405180830381865afa15801561090d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109319190611b59565b155b15610b51576040517fcdc92f2d0000000000000000000000000000000000000000000000000000000081526001600160c01b038b1660048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063cdc92f2d90602401602060405180830381865afa1580156109be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109e29190611be1565b90506109f08160020b610f2d565b82106109fc5750610b51565b5f610a108a60a0015162ffffff1660171c90565b15610a1e5750828403610a38565b60a08a0151610a359062ffffff168587035f610ed8565b90505b60208a015167ffffffffffffffff16610a56600284900b835f6111f5565b610a609190611bc2565b9050805f03610a70575050610b51565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633b9500b060405180606001604052808e81526020018660020b8152602001610ac38661123f565b67ffffffffffffffff168152506040518263ffffffff1660e01b8152600401610aec9190611c01565b60408051808303815f875af1158015610b07573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b2b9190611caa565b915050805f03610b3d57505050610b51565b610b478186611ccc565b945050505061087f565b610b5f8b896040015161128e565b610b6c8b895f015161128e565b60405180602001604052805f8152509b505050505050505050505050610b9061144a565b92915050565b610b9e61146f565b610bb26001600160a01b038416828461149b565b505050565b610bbf61146f565b6001600160a01b0382165f81815260026020908152604091829020805460ff191685151590811790915591519182527f1618a22a3b00b9ac70fd5a82f1f5cdd8cb272bd0f1b740ddf7c26ab05881dd5b910160405180910390a25050565b610c2561146f565b610c2e5f611583565b565b60015433906001600160a01b03168114610c6d5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b610c7681611583565b50565b610c8161146f565b600180546001600160a01b03831673ffffffffffffffffffffffffffffffffffffffff199091168117909155610cbe5f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45c15610d4f576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60017f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45d565b5f6001600160a01b038216610d8b575047919050565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610dcd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b909190611b42565b919050565b5f6207a11f19627fffff851601600281900b82128281610e1857825f03610e1a565b825b62ffffff1690505f610e53610e2f8389611cdf565b620f424088610e45578581830615151691040190565b808206151586151691040190565b905082610e6857610e6381611cf6565b610e6a565b805b98975050505050505050565b5f7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821115610ed4576040517f24775e0600000000000000000000000000000000000000000000000000000000815260048101839052602401610c64565b5090565b5f6207a11f19627fffff851601600281900b8212828415610ef957825f0392505b82620f4240019050610f22620f424087610f139190611cdf565b82810615158416908390040190565b979650505050505050565b5f610f37826115a9565b815f600282900b8113610f4a5781610f53565b610f5382611d2c565b62ffffff8116915060011615610f77576bfff97272373d413259a469909250610f88565b6c0100000000000000000000000092505b6002811615610fa75760606bfff2e50f5f656932ef12357c8402901c92505b6004811615610fc65760606bffe5caca7e10e4e61c3624ea8402901c92505b6008811615610fe55760606bffcb9843d60f6159c9db58838402901c92505b60108116156110045760606bff973b41fa98c081472e68968402901c92505b60208116156110235760606bff2ea16466c96a3843ec78b38402901c92505b60408116156110425760606bfe5dee046a99a2a811c461f18402901c92505b60808116156110615760606bfcbe86c7900a88aedcffc83b8402901c92505b6101008116156110815760606bf987a7253ac413176f2b074c8402901c92505b6102008116156110a15760606bf3392b0822b70005940c7a398402901c92505b6104008116156110c15760606be7159475a2c29b7443b29c7f8402901c92505b6108008116156110e15760606bd097f3bdfd2022b8845ad8f78402901c92505b6110008116156111015760606ba9f746462d870fdf8a65dc1f8402901c92505b6120008116156111215760606b70d869a156d2a1b890bb3df68402901c92505b6140008116156111415760606b31be135f97d08fd9812315058402901c92505b6180008116156111615760606b09aa508b5b7a84e1c677de548402901c92505b620100008116156111815760606a5d6af8dedb81196699c3298402901c92505b620200008116156111a0576060692216e584f5fa1ea926048402901c92505b620400008116156111bd57606067048a170391f7dc428402901c92505b5f8260020b13156111ee576111eb837801000000000000000000000000000000000000000000000000611bc2565b92505b5050919050565b5f6112376112058560020b610f2d565b61120f9085611cdf565b6bffffffffffffffffffffffff8116151584166c010000000000000000000000009091040190565b949350505050565b5f67ffffffffffffffff821115610ed457604080517f6dfcc650000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610c64565b6040517f9611cf6c0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0382811660248301525f917f000000000000000000000000000000000000000000000000000000000000000090911690639611cf6c90604401602060405180830381865afa158015611315573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113399190611b42565b61134290611cf6565b90505f811315611380576113806001600160a01b0383167f00000000000000000000000000000000000000000000000000000000000000008361149b565b6040517f6a256b290000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301527f00000000000000000000000000000000000000000000000000000000000000001690636a256b29906024016020604051808303815f875af11580156113fe573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114229190611b42565b50610bb283611439846001600160a01b0316610d75565b6001600160a01b038516919061149b565b5f7f8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf45d565b5f546001600160a01b03163314610c2e5760405163118cdaa760e01b8152336004820152602401610c64565b5f6001600160a01b0384166114f0575f805f8085875af19050806114eb576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61157d565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f51141617169150508061157d576040517ff27f64e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6001805473ffffffffffffffffffffffffffffffffffffffff19169055610c7681611605565b6207ffff600282900b13806115ce57506115c56207ffff611d2c565b60020b8160020b125b15610c76576040517fce8ef7fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160c01b0381168114610c76575f80fd5b6001600160a01b0381168114610c76575f80fd5b5f805f806060858703121561169c575f80fd5b84356116a781611661565b935060208501356116b781611675565b9250604085013567ffffffffffffffff808211156116d3575f80fd5b818701915087601f8301126116e6575f80fd5b8135818111156116f4575f80fd5b886020828501011115611705575f80fd5b95989497505060200194505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561175157611751611714565b604052919050565b5f67ffffffffffffffff82111561177257611772611714565b50601f01601f191660200190565b5f8060408385031215611791575f80fd5b823561179c81611675565b9150602083013567ffffffffffffffff8111156117b7575f80fd5b8301601f810185136117c7575f80fd5b80356117da6117d582611759565b611728565b8181528660208385010111156117ee575f80fd5b816020840160208301375f602083830101528093505050509250929050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61184d602083018461180d565b9392505050565b5f805f60608486031215611866575f80fd5b833561187181611675565b925060208401359150604084013561188881611675565b809150509250925092565b8015158114610c76575f80fd5b5f80604083850312156118b1575f80fd5b82356118bc81611675565b915060208301356118cc81611893565b809150509250929050565b5f602082840312156118e7575f80fd5b813561184d81611675565b5f6001600160a01b0380881683526001600160c01b038716602084015280861660408401525060806060830152826080830152828460a08401375f60a0848401015260a0601f19601f85011683010190509695505050505050565b6001600160a01b0383168152604060208201525f611237604083018461180d565b5f82601f83011261197d575f80fd5b815161198b6117d582611759565b81815284602083860101111561199f575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f602082840312156119cb575f80fd5b815167ffffffffffffffff8111156119e1575f80fd5b6112378482850161196e565b5f805f8060808587031215611a00575f80fd5b8451611a0b81611675565b6020860151909450611a1c81611661565b6040860151909350611a2d81611675565b606086015190925067ffffffffffffffff811115611a49575f80fd5b611a558782880161196e565b91505092959194509250565b805162ffffff81168114610df1575f80fd5b8051610df181611675565b5f60c08284031215611a8e575f80fd5b60405160c0810167ffffffffffffffff8282108183111715611ab257611ab2611714565b8160405284519150611ac382611675565b9082526020840151908082168214611ad9575f80fd5b5060208201526040830151611aed81611675565b6040820152611afe60608401611a61565b6060820152611b0f60808401611a73565b6080820152611b2060a08401611a61565b60a08201529392505050565b5f82518060208501845e5f920191825250919050565b5f60208284031215611b52575f80fd5b5051919050565b5f60208284031215611b69575f80fd5b815161184d81611893565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610b9057610b90611b74565b8082018281125f831280158216821582161715611bba57611bba611b74565b505092915050565b5f82611bdc57634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215611bf1575f80fd5b81518060020b811461184d575f80fd5b5f61012083516001600160a01b0380825116855267ffffffffffffffff602083015116602086015280604083015116604086015262ffffff60608301511660608601528060808301511660808601525060a08101519050611c6960a085018262ffffff169052565b506020840151611c7e60c085018260020b9052565b50604084015167ffffffffffffffff1660e084015261010083018190525f818401908152602001611237565b5f8060408385031215611cbb575f80fd5b505080516020909101519092909150565b80820180821115610b9057610b90611b74565b8082028115828204841417610b9057610b90611b74565b5f7f80000000000000000000000000000000000000000000000000000000000000008203611d2657611d26611b74565b505f0390565b5f8160020b627fffff198103611d4457611d44611b74565b5f039291505056fea26469706673582212203d102bafa2cceb63221cf5fed2d181aa828f35df49d2c386bc2aab4b700b2a3064736f6c63430008190033", + "devdoc": { + "errors": { + "OwnableInvalidOwner(address)": [ + { + "details": "The owner is not a valid owner account. (eg. `address(0)`)" + } + ], + "OwnableUnauthorizedAccount(address)": [ + { + "details": "The caller account is not authorized to perform an operation." + } + ], + "SafeCastOverflowedUintDowncast(uint8,uint256)": [ + { + "details": "Value doesn't fit in an uint of `bits` size." + } + ], + "SafeCastOverflowedUintToInt(uint256)": [ + { + "details": "An uint value doesn't fit in an int of `bits` size." + } + ] + }, + "kind": "dev", + "methods": { + "acceptOwnership()": { + "details": "The new owner accepts the ownership transfer." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "pendingOwner()": { + "details": "Returns the address of the pending owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "errors": { + "ERC20TransferFailed()": [ + { + "notice": "Thrown when an ERC20 transfer fails" + } + ], + "NativeTransferFailed()": [ + { + "notice": "Thrown when a native transfer fails" + } + ] + }, + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 8, + "contract": "src/Arbitrage.sol:Arbitrage", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 156, + "contract": "src/Arbitrage.sol:Arbitrage", + "label": "_pendingOwner", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 4290, + "contract": "src/Arbitrage.sol:Arbitrage", + "label": "isOperator", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_bool)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + } + } + } +} \ No newline at end of file diff --git a/deployments/8453/solcInputs/e634729b678ce078f381c6f26baf2f0d.json b/deployments/8453/solcInputs/e634729b678ce078f381c6f26baf2f0d.json new file mode 100644 index 0000000..dfeb5fc --- /dev/null +++ b/deployments/8453/solcInputs/e634729b678ce078f381c6f26baf2f0d.json @@ -0,0 +1,174 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n /**\n * @dev The caller account is not authorized to perform an operation.\n */\n error OwnableUnauthorizedAccount(address account);\n\n /**\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\n */\n error OwnableInvalidOwner(address owner);\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n */\n constructor(address initialOwner) {\n if (initialOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(initialOwner);\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n if (owner() != _msgSender()) {\n revert OwnableUnauthorizedAccount(_msgSender());\n }\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n if (newOwner == address(0)) {\n revert OwnableInvalidOwner(address(0));\n }\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.20;\n\nimport {Ownable} from \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This extension of the {Ownable} contract includes a two-step mechanism to transfer\n * ownership, where the new owner must call {acceptOwnership} in order to replace the\n * old one. This can help prevent common mistakes, such as transfers of ownership to\n * incorrect accounts, or to contracts that are unable to interact with the\n * permission system.\n *\n * The initial owner is specified at deployment time in the constructor for `Ownable`. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n if (pendingOwner() != sender) {\n revert OwnableUnauthorizedAccount(sender);\n }\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev ERC-1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1363.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1363.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n /*\n * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n * 0xb0202a11 ===\n * bytes4(keccak256('transferAndCall(address,uint256)')) ^\n * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n * bytes4(keccak256('approveAndCall(address,uint256)')) ^\n * bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n */\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`\n * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n * @param to The address which you want to transfer to.\n * @param value The amount of tokens to be transferred.\n * @return A boolean value indicating whether the operation succeeded unless throwing.\n */\n function transferAndCall(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`\n * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n * @param to The address which you want to transfer to.\n * @param value The amount of tokens to be transferred.\n * @param data Additional data with no specified format, sent in call to `to`.\n * @return A boolean value indicating whether the operation succeeded unless throwing.\n */\n function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n * @param from The address which you want to send tokens from.\n * @param to The address which you want to transfer to.\n * @param value The amount of tokens to be transferred.\n * @return A boolean value indicating whether the operation succeeded unless throwing.\n */\n function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n * @param from The address which you want to send tokens from.\n * @param to The address which you want to transfer to.\n * @param value The amount of tokens to be transferred.\n * @param data Additional data with no specified format, sent in call to `to`.\n * @return A boolean value indicating whether the operation succeeded unless throwing.\n */\n function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n * @param spender The address which will spend the funds.\n * @param value The amount of tokens to be spent.\n * @return A boolean value indicating whether the operation succeeded unless throwing.\n */\n function approveAndCall(address spender, uint256 value) external returns (bool);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n * @param spender The address which will spend the funds.\n * @param value The amount of tokens to be spent.\n * @param data Additional data with no specified format, sent in call to `spender`.\n * @return A boolean value indicating whether the operation succeeded unless throwing.\n */\n function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n" + }, + "@openzeppelin/contracts/interfaces/IERC1967.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n */\ninterface IERC1967 {\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Emitted when the beacon is changed.\n */\n event BeaconUpgraded(address indexed beacon);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {UpgradeableBeacon} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.20;\n\nimport {Proxy} from \"../Proxy.sol\";\nimport {ERC1967Utils} from \"./ERC1967Utils.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an\n * encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\n *\n * Requirements:\n *\n * - If `data` is empty, `msg.value` must be zero.\n */\n constructor(address implementation, bytes memory _data) payable {\n ERC1967Utils.upgradeToAndCall(implementation, _data);\n }\n\n /**\n * @dev Returns the current implementation address.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using\n * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function _implementation() internal view virtual override returns (address) {\n return ERC1967Utils.getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)\n\npragma solidity ^0.8.21;\n\nimport {IBeacon} from \"../beacon/IBeacon.sol\";\nimport {IERC1967} from \"../../interfaces/IERC1967.sol\";\nimport {Address} from \"../../utils/Address.sol\";\nimport {StorageSlot} from \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots.\n */\nlibrary ERC1967Utils {\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1.\n */\n // solhint-disable-next-line private-vars-leading-underscore\n bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev The `implementation` of the proxy is invalid.\n */\n error ERC1967InvalidImplementation(address implementation);\n\n /**\n * @dev The `admin` of the proxy is invalid.\n */\n error ERC1967InvalidAdmin(address admin);\n\n /**\n * @dev The `beacon` of the proxy is invalid.\n */\n error ERC1967InvalidBeacon(address beacon);\n\n /**\n * @dev An upgrade function sees `msg.value > 0` that may be lost.\n */\n error ERC1967NonPayable();\n\n /**\n * @dev Returns the current implementation address.\n */\n function getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the ERC-1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n if (newImplementation.code.length == 0) {\n revert ERC1967InvalidImplementation(newImplementation);\n }\n StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Performs implementation upgrade with additional setup call if data is nonempty.\n * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n * to avoid stuck value in the contract.\n *\n * Emits an {IERC1967-Upgraded} event.\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) internal {\n _setImplementation(newImplementation);\n emit IERC1967.Upgraded(newImplementation);\n\n if (data.length > 0) {\n Address.functionDelegateCall(newImplementation, data);\n } else {\n _checkNonPayable();\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1.\n */\n // solhint-disable-next-line private-vars-leading-underscore\n bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Returns the current admin.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using\n * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the ERC-1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n if (newAdmin == address(0)) {\n revert ERC1967InvalidAdmin(address(0));\n }\n StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {IERC1967-AdminChanged} event.\n */\n function changeAdmin(address newAdmin) internal {\n emit IERC1967.AdminChanged(getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is the keccak-256 hash of \"eip1967.proxy.beacon\" subtracted by 1.\n */\n // solhint-disable-next-line private-vars-leading-underscore\n bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Returns the current beacon.\n */\n function getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the ERC-1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n if (newBeacon.code.length == 0) {\n revert ERC1967InvalidBeacon(newBeacon);\n }\n\n StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;\n\n address beaconImplementation = IBeacon(newBeacon).implementation();\n if (beaconImplementation.code.length == 0) {\n revert ERC1967InvalidImplementation(beaconImplementation);\n }\n }\n\n /**\n * @dev Change the beacon and trigger a setup call if data is nonempty.\n * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n * to avoid stuck value in the contract.\n *\n * Emits an {IERC1967-BeaconUpgraded} event.\n *\n * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since\n * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for\n * efficiency.\n */\n function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {\n _setBeacon(newBeacon);\n emit IERC1967.BeaconUpgraded(newBeacon);\n\n if (data.length > 0) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n } else {\n _checkNonPayable();\n }\n }\n\n /**\n * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract\n * if an upgrade doesn't perform an initialization call.\n */\n function _checkNonPayable() private {\n if (msg.value > 0) {\n revert ERC1967NonPayable();\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback\n * function and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Storage of the initializable contract.\n *\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n * when using with upgradeable contracts.\n *\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n */\n struct InitializableStorage {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n uint64 _initialized;\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool _initializing;\n }\n\n // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n /**\n * @dev The contract is already initialized.\n */\n error InvalidInitialization();\n\n /**\n * @dev The contract is not initializing.\n */\n error NotInitializing();\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint64 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n * production.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n // solhint-disable-next-line var-name-mixedcase\n InitializableStorage storage $ = _getInitializableStorage();\n\n // Cache values to avoid duplicated sloads\n bool isTopLevelCall = !$._initializing;\n uint64 initialized = $._initialized;\n\n // Allowed calls:\n // - initialSetup: the contract is not in the initializing state and no previous version was\n // initialized\n // - construction: the contract is initialized at version 1 (no reininitialization) and the\n // current contract is just being deployed\n bool initialSetup = initialized == 0 && isTopLevelCall;\n bool construction = initialized == 1 && address(this).code.length == 0;\n\n if (!initialSetup && !construction) {\n revert InvalidInitialization();\n }\n $._initialized = 1;\n if (isTopLevelCall) {\n $._initializing = true;\n }\n _;\n if (isTopLevelCall) {\n $._initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint64 version) {\n // solhint-disable-next-line var-name-mixedcase\n InitializableStorage storage $ = _getInitializableStorage();\n\n if ($._initializing || $._initialized >= version) {\n revert InvalidInitialization();\n }\n $._initialized = version;\n $._initializing = true;\n _;\n $._initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n _checkInitializing();\n _;\n }\n\n /**\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n */\n function _checkInitializing() internal view virtual {\n if (!_isInitializing()) {\n revert NotInitializing();\n }\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n // solhint-disable-next-line var-name-mixedcase\n InitializableStorage storage $ = _getInitializableStorage();\n\n if ($._initializing) {\n revert InvalidInitialization();\n }\n if ($._initialized != type(uint64).max) {\n $._initialized = type(uint64).max;\n emit Initialized(type(uint64).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint64) {\n return _getInitializableStorage()._initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _getInitializableStorage()._initializing;\n }\n\n /**\n * @dev Returns a pointer to the storage namespace.\n */\n // solhint-disable-next-line var-name-mixedcase\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n assembly {\n $.slot := INITIALIZABLE_STORAGE\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC1822Proxiable} from \"../../interfaces/draft-IERC1822.sol\";\nimport {ERC1967Utils} from \"../ERC1967/ERC1967Utils.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n */\nabstract contract UUPSUpgradeable is IERC1822Proxiable {\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n address private immutable __self = address(this);\n\n /**\n * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`\n * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,\n * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.\n * If the getter returns `\"5.0.0\"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must\n * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function\n * during an upgrade.\n */\n string public constant UPGRADE_INTERFACE_VERSION = \"5.0.0\";\n\n /**\n * @dev The call is from an unauthorized context.\n */\n error UUPSUnauthorizedCallContext();\n\n /**\n * @dev The storage `slot` is unsupported as a UUID.\n */\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC-1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC-1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n _checkProxy();\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n _checkNotDelegated();\n _;\n }\n\n /**\n * @dev Implementation of the ERC-1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual notDelegated returns (bytes32) {\n return ERC1967Utils.IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n *\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data);\n }\n\n /**\n * @dev Reverts if the execution is not performed via delegatecall or the execution\n * context is not of a proxy with an ERC-1967 compliant implementation pointing to self.\n * See {_onlyProxy}.\n */\n function _checkProxy() internal view virtual {\n if (\n address(this) == __self || // Must be called through delegatecall\n ERC1967Utils.getImplementation() != __self // Must be called through an active proxy\n ) {\n revert UUPSUnauthorizedCallContext();\n }\n }\n\n /**\n * @dev Reverts if the execution is performed via delegatecall.\n * See {notDelegated}.\n */\n function _checkNotDelegated() internal view virtual {\n if (address(this) != __self) {\n // Must not be called through delegatecall\n revert UUPSUnauthorizedCallContext();\n }\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\n\n /**\n * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.\n *\n * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value\n * is expected to be the implementation slot in ERC-1967.\n *\n * Emits an {IERC1967-Upgraded} event.\n */\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {\n revert UUPSUnsupportedProxiableUUID(slot);\n }\n ERC1967Utils.upgradeToAndCall(newImplementation, data);\n } catch {\n // The implementation is not UUPS\n revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[ERC-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC-20 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 *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n * doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n * token.safeTransferFrom(msg.sender, address(this), value);\n * ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\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 * CAUTION: See Security Considerations above.\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 v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\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 value of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the value of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens as the allowance of `spender` over the\n * 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 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\n * allowance mechanism. `value` 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 value) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\nimport {Address} from \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 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 /**\n * @dev An operation with an ERC-20 token failed.\n */\n error SafeERC20FailedOperation(address token);\n\n /**\n * @dev Indicates a failed `decreaseAllowance` request.\n */\n error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\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.encodeCall(token.transfer, (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.encodeCall(token.transferFrom, (from, to, 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 forceApprove(token, spender, oldAllowance + value);\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n * value, non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n unchecked {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < requestedDecrease) {\n revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n }\n forceApprove(token, spender, currentAllowance - requestedDecrease);\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.encodeCall(token.approve, (spender, value));\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n * targeting contracts.\n *\n * Reverts if the returned value is other than `true`.\n */\n function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n if (to.code.length == 0) {\n safeTransfer(token, to, value);\n } else if (!token.transferAndCall(to, value, data)) {\n revert SafeERC20FailedOperation(address(token));\n }\n }\n\n /**\n * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n * targeting contracts.\n *\n * Reverts if the returned value is other than `true`.\n */\n function transferFromAndCallRelaxed(\n IERC1363 token,\n address from,\n address to,\n uint256 value,\n bytes memory data\n ) internal {\n if (to.code.length == 0) {\n safeTransferFrom(token, from, to, value);\n } else if (!token.transferFromAndCall(from, to, value, data)) {\n revert SafeERC20FailedOperation(address(token));\n }\n }\n\n /**\n * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n * targeting contracts.\n *\n * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n * once without retrying, and relies on the returned value to be true.\n *\n * Reverts if the returned value is other than `true`.\n */\n function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n if (to.code.length == 0) {\n forceApprove(token, to, value);\n } else if (!token.approveAndCall(to, value, data)) {\n revert SafeERC20FailedOperation(address(token));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param 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 {_callOptionalReturnBool} that reverts if call fails to meet the requirements.\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n uint256 returnSize;\n uint256 returnValue;\n assembly (\"memory-safe\") {\n let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n // bubble errors\n if iszero(success) {\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize())\n revert(ptr, returndatasize())\n }\n returnSize := returndatasize()\n returnValue := mload(0)\n }\n\n if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {\n revert SafeERC20FailedOperation(address(token));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param 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 silently catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly (\"memory-safe\") {\n success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0)\n }\n return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC721} from \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC-721 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\n * 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 ERC-721 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\n * {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\n * 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 ERC-721\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 address zero.\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/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\nimport {Errors} from \"./Errors.sol\";\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev There's no code at `target` (it is not a contract).\n */\n error AddressEmptyCode(address target);\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.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n if (address(this).balance < amount) {\n revert Errors.InsufficientBalance(address(this).balance, amount);\n }\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n if (!success) {\n revert Errors.FailedCall();\n }\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 or custom error, it is bubbled\n * up by this function (like regular Solidity function calls). However, if\n * the call reverted with no returned reason, this function reverts with a\n * {Errors.FailedCall} error.\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 function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0);\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 function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n if (address(this).balance < value) {\n revert Errors.InsufficientBalance(address(this).balance, value);\n }\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case\n * of an unsuccessful call.\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata\n ) internal view returns (bytes memory) {\n if (!success) {\n _revert(returndata);\n } else {\n // only check if target is a contract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n if (returndata.length == 0 && target.code.length == 0) {\n revert AddressEmptyCode(target);\n }\n return returndata;\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n * revert reason or with a default {Errors.FailedCall} error.\n */\n function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n if (!success) {\n _revert(returndata);\n } else {\n return returndata;\n }\n }\n\n /**\n * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.\n */\n function _revert(bytes memory returndata) 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 Errors.FailedCall();\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of common custom errors used in multiple contracts\n *\n * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.\n * It is recommended to avoid relying on the error API for critical functionality.\n */\nlibrary Errors {\n /**\n * @dev The ETH balance of the account is not enough to perform the operation.\n */\n error InsufficientBalance(uint256 balance, uint256 needed);\n\n /**\n * @dev A call to an address target failed. The target may have reverted.\n */\n error FailedCall();\n\n /**\n * @dev The deployment failed.\n */\n error FailedDeployment();\n\n /**\n * @dev A necessary precompile is missing.\n */\n error MissingPrecompile(address);\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\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[ERC 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" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n /**\n * @dev Value doesn't fit in an uint of `bits` size.\n */\n error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n /**\n * @dev An int value doesn't fit in an uint of `bits` size.\n */\n error SafeCastOverflowedIntToUint(int256 value);\n\n /**\n * @dev Value doesn't fit in an int of `bits` size.\n */\n error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n /**\n * @dev An uint value doesn't fit in an int of `bits` size.\n */\n error SafeCastOverflowedUintToInt(uint256 value);\n\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n if (value > type(uint248).max) {\n revert SafeCastOverflowedUintDowncast(248, value);\n }\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n if (value > type(uint240).max) {\n revert SafeCastOverflowedUintDowncast(240, value);\n }\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n if (value > type(uint232).max) {\n revert SafeCastOverflowedUintDowncast(232, value);\n }\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n if (value > type(uint224).max) {\n revert SafeCastOverflowedUintDowncast(224, value);\n }\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n if (value > type(uint216).max) {\n revert SafeCastOverflowedUintDowncast(216, value);\n }\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n if (value > type(uint208).max) {\n revert SafeCastOverflowedUintDowncast(208, value);\n }\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n if (value > type(uint200).max) {\n revert SafeCastOverflowedUintDowncast(200, value);\n }\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n if (value > type(uint192).max) {\n revert SafeCastOverflowedUintDowncast(192, value);\n }\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n if (value > type(uint184).max) {\n revert SafeCastOverflowedUintDowncast(184, value);\n }\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n if (value > type(uint176).max) {\n revert SafeCastOverflowedUintDowncast(176, value);\n }\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n if (value > type(uint168).max) {\n revert SafeCastOverflowedUintDowncast(168, value);\n }\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n if (value > type(uint160).max) {\n revert SafeCastOverflowedUintDowncast(160, value);\n }\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n if (value > type(uint152).max) {\n revert SafeCastOverflowedUintDowncast(152, value);\n }\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n if (value > type(uint144).max) {\n revert SafeCastOverflowedUintDowncast(144, value);\n }\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n if (value > type(uint136).max) {\n revert SafeCastOverflowedUintDowncast(136, value);\n }\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n if (value > type(uint128).max) {\n revert SafeCastOverflowedUintDowncast(128, value);\n }\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n if (value > type(uint120).max) {\n revert SafeCastOverflowedUintDowncast(120, value);\n }\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n if (value > type(uint112).max) {\n revert SafeCastOverflowedUintDowncast(112, value);\n }\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n if (value > type(uint104).max) {\n revert SafeCastOverflowedUintDowncast(104, value);\n }\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n if (value > type(uint96).max) {\n revert SafeCastOverflowedUintDowncast(96, value);\n }\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n if (value > type(uint88).max) {\n revert SafeCastOverflowedUintDowncast(88, value);\n }\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n if (value > type(uint80).max) {\n revert SafeCastOverflowedUintDowncast(80, value);\n }\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n if (value > type(uint72).max) {\n revert SafeCastOverflowedUintDowncast(72, value);\n }\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n if (value > type(uint64).max) {\n revert SafeCastOverflowedUintDowncast(64, value);\n }\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n if (value > type(uint56).max) {\n revert SafeCastOverflowedUintDowncast(56, value);\n }\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n if (value > type(uint48).max) {\n revert SafeCastOverflowedUintDowncast(48, value);\n }\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n if (value > type(uint40).max) {\n revert SafeCastOverflowedUintDowncast(40, value);\n }\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n if (value > type(uint32).max) {\n revert SafeCastOverflowedUintDowncast(32, value);\n }\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n if (value > type(uint24).max) {\n revert SafeCastOverflowedUintDowncast(24, value);\n }\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n if (value > type(uint16).max) {\n revert SafeCastOverflowedUintDowncast(16, value);\n }\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n if (value > type(uint8).max) {\n revert SafeCastOverflowedUintDowncast(8, value);\n }\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n if (value < 0) {\n revert SafeCastOverflowedIntToUint(value);\n }\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(248, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(240, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(232, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(224, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(216, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(208, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(200, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(192, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(184, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(176, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(168, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(160, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(152, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(144, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(136, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(128, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(120, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(112, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(104, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(96, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(88, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(80, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(72, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(64, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(56, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(48, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(40, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(32, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(24, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(16, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(8, value);\n }\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n if (value > uint256(type(int256).max)) {\n revert SafeCastOverflowedUintToInt(value);\n }\n return int256(value);\n }\n\n /**\n * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n */\n function toUint(bool b) internal pure returns (uint256 u) {\n /// @solidity memory-safe-assembly\n assembly {\n u := iszero(iszero(b))\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.24;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(newImplementation.code.length > 0);\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * Since version 5.1, this library also support writing and reading value types to and from transient storage.\n *\n * * Example using transient storage:\n * ```solidity\n * contract Lock {\n * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n * bytes32 internal constant _LOCK_SLOT = 0xf4678858b2b588224636b8522b729e7722d32fc491da849ed75b3fdf3c84f542;\n *\n * modifier locked() {\n * require(!_LOCK_SLOT.asBoolean().tload());\n *\n * _LOCK_SLOT.asBoolean().tstore(true);\n * _;\n * _LOCK_SLOT.asBoolean().tstore(false);\n * }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n struct Int256Slot {\n int256 value;\n }\n\n struct StringSlot {\n string value;\n }\n\n struct BytesSlot {\n bytes value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Int256Slot` with member `value` located at `slot`.\n */\n function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\n */\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n */\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n */\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n */\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev UDVT that represent a slot holding a address.\n */\n type AddressSlotType is bytes32;\n\n /**\n * @dev Cast an arbitrary slot to a AddressSlotType.\n */\n function asAddress(bytes32 slot) internal pure returns (AddressSlotType) {\n return AddressSlotType.wrap(slot);\n }\n\n /**\n * @dev UDVT that represent a slot holding a bool.\n */\n type BooleanSlotType is bytes32;\n\n /**\n * @dev Cast an arbitrary slot to a BooleanSlotType.\n */\n function asBoolean(bytes32 slot) internal pure returns (BooleanSlotType) {\n return BooleanSlotType.wrap(slot);\n }\n\n /**\n * @dev UDVT that represent a slot holding a bytes32.\n */\n type Bytes32SlotType is bytes32;\n\n /**\n * @dev Cast an arbitrary slot to a Bytes32SlotType.\n */\n function asBytes32(bytes32 slot) internal pure returns (Bytes32SlotType) {\n return Bytes32SlotType.wrap(slot);\n }\n\n /**\n * @dev UDVT that represent a slot holding a uint256.\n */\n type Uint256SlotType is bytes32;\n\n /**\n * @dev Cast an arbitrary slot to a Uint256SlotType.\n */\n function asUint256(bytes32 slot) internal pure returns (Uint256SlotType) {\n return Uint256SlotType.wrap(slot);\n }\n\n /**\n * @dev UDVT that represent a slot holding a int256.\n */\n type Int256SlotType is bytes32;\n\n /**\n * @dev Cast an arbitrary slot to a Int256SlotType.\n */\n function asInt256(bytes32 slot) internal pure returns (Int256SlotType) {\n return Int256SlotType.wrap(slot);\n }\n\n /**\n * @dev Load the value held at location `slot` in transient storage.\n */\n function tload(AddressSlotType slot) internal view returns (address value) {\n /// @solidity memory-safe-assembly\n assembly {\n value := tload(slot)\n }\n }\n\n /**\n * @dev Store `value` at location `slot` in transient storage.\n */\n function tstore(AddressSlotType slot, address value) internal {\n /// @solidity memory-safe-assembly\n assembly {\n tstore(slot, value)\n }\n }\n\n /**\n * @dev Load the value held at location `slot` in transient storage.\n */\n function tload(BooleanSlotType slot) internal view returns (bool value) {\n /// @solidity memory-safe-assembly\n assembly {\n value := tload(slot)\n }\n }\n\n /**\n * @dev Store `value` at location `slot` in transient storage.\n */\n function tstore(BooleanSlotType slot, bool value) internal {\n /// @solidity memory-safe-assembly\n assembly {\n tstore(slot, value)\n }\n }\n\n /**\n * @dev Load the value held at location `slot` in transient storage.\n */\n function tload(Bytes32SlotType slot) internal view returns (bytes32 value) {\n /// @solidity memory-safe-assembly\n assembly {\n value := tload(slot)\n }\n }\n\n /**\n * @dev Store `value` at location `slot` in transient storage.\n */\n function tstore(Bytes32SlotType slot, bytes32 value) internal {\n /// @solidity memory-safe-assembly\n assembly {\n tstore(slot, value)\n }\n }\n\n /**\n * @dev Load the value held at location `slot` in transient storage.\n */\n function tload(Uint256SlotType slot) internal view returns (uint256 value) {\n /// @solidity memory-safe-assembly\n assembly {\n value := tload(slot)\n }\n }\n\n /**\n * @dev Store `value` at location `slot` in transient storage.\n */\n function tstore(Uint256SlotType slot, uint256 value) internal {\n /// @solidity memory-safe-assembly\n assembly {\n tstore(slot, value)\n }\n }\n\n /**\n * @dev Load the value held at location `slot` in transient storage.\n */\n function tload(Int256SlotType slot) internal view returns (int256 value) {\n /// @solidity memory-safe-assembly\n assembly {\n value := tload(slot)\n }\n }\n\n /**\n * @dev Store `value` at location `slot` in transient storage.\n */\n function tstore(Int256SlotType slot, int256 value) internal {\n /// @solidity memory-safe-assembly\n assembly {\n tstore(slot, value)\n }\n }\n}\n" + }, + "src/Arbitrage.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {Ownable, Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\nimport {ILocker} from \"v2-core/interfaces/ILocker.sol\";\nimport {IHooks} from \"v2-core/interfaces/IHooks.sol\";\nimport {BookId, BookIdLibrary} from \"v2-core/libraries/BookId.sol\";\nimport {Currency, CurrencyLibrary} from \"v2-core/libraries/Currency.sol\";\nimport {FeePolicy, FeePolicyLibrary} from \"v2-core/libraries/FeePolicy.sol\";\nimport {Tick, TickLibrary} from \"v2-core/libraries/Tick.sol\";\nimport {ReentrancyGuard} from \"./libraries/ReentrancyGuard.sol\";\nimport {IArbitrage} from \"./interfaces/IArbitrage.sol\";\n\ncontract Arbitrage is IArbitrage, Ownable2Step, ILocker, ReentrancyGuard {\n using TickLibrary for Tick;\n using SafeCast for uint256;\n using CurrencyLibrary for Currency;\n using FeePolicyLibrary for FeePolicy;\n\n IBookManager public immutable bookManager;\n\n mapping(address => bool) public isOperator;\n\n modifier onlyOperator() {\n if (!isOperator[msg.sender]) revert NotOperator();\n _;\n }\n\n constructor(address bookManager_, address initialOwner_) Ownable(initialOwner_) {\n bookManager = IBookManager(bookManager_);\n }\n\n function setOperator(address operator, bool status) external onlyOwner {\n isOperator[operator] = status;\n emit SetOperator(operator, status);\n }\n\n function lockAcquired(address sender, bytes memory data) external nonReentrant returns (bytes memory) {\n if (msg.sender != address(bookManager) || sender != address(this)) revert InvalidAccess();\n address user;\n BookId id;\n address router;\n (user, id, router, data) = abi.decode(data, (address, BookId, address, bytes));\n\n IBookManager.BookKey memory key = bookManager.getBookKey(id);\n uint256 max;\n bool success;\n bytes memory returnData;\n if (key.quote.isNative()) {\n max = address(bookManager).balance;\n bookManager.withdraw(key.quote, address(this), max);\n (success, returnData) = router.call{value: max}(data);\n } else {\n IERC20 quote = IERC20(Currency.unwrap(key.quote));\n max = quote.balanceOf(address(bookManager));\n quote.approve(router, max);\n (success, returnData) = router.call(data);\n quote.approve(router, 0);\n }\n if (!success) revert();\n\n uint256 quoteAmount = max - key.quote.balanceOfSelf();\n uint256 baseAmount = key.base.balanceOfSelf();\n uint256 spentBaseAmount;\n uint256 price;\n if (key.takerPolicy.usesQuote()) {\n quoteAmount = uint256(quoteAmount.toInt256() + key.takerPolicy.calculateFee(quoteAmount, false));\n price = (quoteAmount << 96) / baseAmount;\n } else {\n price = (quoteAmount << 96) / key.takerPolicy.calculateOriginalAmount(baseAmount, false);\n }\n\n while (spentBaseAmount < baseAmount && !bookManager.isEmpty(id)) {\n Tick tick = bookManager.getHighest(id);\n if (price >= tick.toPrice()) break; // Did not consider fees.\n uint256 maxAmount;\n unchecked {\n if (key.takerPolicy.usesQuote()) {\n maxAmount = baseAmount - spentBaseAmount;\n } else {\n maxAmount = key.takerPolicy.calculateOriginalAmount(baseAmount - spentBaseAmount, false);\n }\n }\n maxAmount = tick.baseToQuote(maxAmount, false) / key.unitSize;\n if (maxAmount == 0) break;\n (, uint256 amount) =\n bookManager.take(IBookManager.TakeParams({key: key, tick: tick, maxUnit: maxAmount.toUint64()}), \"\");\n if (amount == 0) break;\n spentBaseAmount += amount;\n }\n\n _settleCurrency(user, key.quote);\n _settleCurrency(user, key.base);\n\n return \"\";\n }\n\n function arbitrage(BookId id, address router, bytes calldata data) external onlyOperator {\n bookManager.lock(address(this), abi.encode(msg.sender, id, router, data));\n }\n\n function _settleCurrency(address user, Currency currency) internal {\n int256 currencyDelta = -bookManager.getCurrencyDelta(address(this), currency);\n if (currencyDelta > 0) {\n currency.transfer(address(bookManager), uint256(currencyDelta));\n }\n bookManager.settle(currency);\n currency.transfer(user, currency.balanceOfSelf());\n }\n\n function withdrawToken(Currency currency, uint256 amount, address recipient) external onlyOwner {\n currency.transfer(recipient, amount);\n }\n\n receive() external payable {}\n}\n" + }, + "src/BookViewer.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol\";\nimport {ERC1967Proxy} from \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\"; // To generate artifacts\nimport {Ownable, Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {Initializable} from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\nimport {SignificantBit} from \"v2-core/libraries/SignificantBit.sol\";\nimport {Math} from \"v2-core/libraries/Math.sol\";\nimport {Lockers} from \"v2-core/libraries/Lockers.sol\";\nimport {BookId} from \"v2-core/libraries/BookId.sol\";\nimport {Tick, TickLibrary} from \"v2-core/libraries/Tick.sol\";\nimport {FeePolicy, FeePolicyLibrary} from \"v2-core/libraries/FeePolicy.sol\";\n\nimport {IBookViewer} from \"./interfaces/IBookViewer.sol\";\nimport {IController} from \"./interfaces/IController.sol\";\n\ncontract BookViewer is IBookViewer, UUPSUpgradeable, Ownable2Step, Initializable {\n using SafeCast for *;\n using TickLibrary for *;\n using Math for uint256;\n using SignificantBit for uint256;\n using FeePolicyLibrary for FeePolicy;\n\n IBookManager public immutable bookManager;\n\n constructor(IBookManager bookManager_) Ownable(msg.sender) {\n bookManager = bookManager_;\n }\n\n function __BookViewer_init(address owner) external initializer {\n _transferOwnership(owner);\n }\n\n function _authorizeUpgrade(address) internal override onlyOwner {}\n\n function getLiquidity(BookId id, Tick tick, uint256 n) external view returns (Liquidity[] memory liquidity) {\n liquidity = new Liquidity[](n);\n if (bookManager.getDepth(id, tick) == 0) tick = bookManager.maxLessThan(id, tick);\n uint256 i;\n while (i < n) {\n if (Tick.unwrap(tick) == type(int24).min) break;\n liquidity[i] = Liquidity({tick: tick, depth: bookManager.getDepth(id, tick)});\n tick = bookManager.maxLessThan(id, tick);\n unchecked {\n ++i;\n }\n }\n assembly {\n mstore(liquidity, i)\n }\n }\n\n function getExpectedInput(IController.TakeOrderParams memory params)\n external\n view\n returns (uint256 takenQuoteAmount, uint256 spentBaseAmount)\n {\n IBookManager.BookKey memory key = bookManager.getBookKey(params.id);\n\n if (bookManager.isEmpty(params.id)) return (0, 0);\n\n Tick tick = bookManager.getHighest(params.id);\n\n while (Tick.unwrap(tick) > type(int24).min) {\n unchecked {\n if (params.limitPrice > tick.toPrice()) break;\n uint256 maxAmount;\n if (key.takerPolicy.usesQuote()) {\n maxAmount = key.takerPolicy.calculateOriginalAmount(params.quoteAmount - takenQuoteAmount, true);\n } else {\n maxAmount = params.quoteAmount - takenQuoteAmount;\n }\n maxAmount = maxAmount.divide(key.unitSize, true);\n\n if (maxAmount == 0) break;\n uint256 currentDepth = bookManager.getDepth(params.id, tick);\n uint256 quoteAmount = (currentDepth > maxAmount ? maxAmount : currentDepth) * key.unitSize;\n uint256 baseAmount = tick.quoteToBase(quoteAmount, true);\n if (key.takerPolicy.usesQuote()) {\n quoteAmount = uint256(int256(quoteAmount) - key.takerPolicy.calculateFee(quoteAmount, false));\n } else {\n baseAmount = uint256(baseAmount.toInt256() + key.takerPolicy.calculateFee(baseAmount, false));\n }\n if (quoteAmount == 0) break;\n\n takenQuoteAmount += quoteAmount;\n spentBaseAmount += baseAmount;\n if (params.quoteAmount <= takenQuoteAmount) break;\n tick = bookManager.maxLessThan(params.id, tick);\n }\n }\n }\n\n function getExpectedOutput(IController.SpendOrderParams memory params)\n external\n view\n returns (uint256 takenQuoteAmount, uint256 spentBaseAmount)\n {\n IBookManager.BookKey memory key = bookManager.getBookKey(params.id);\n\n if (bookManager.isEmpty(params.id)) return (0, 0);\n\n Tick tick = bookManager.getHighest(params.id);\n\n unchecked {\n while (spentBaseAmount <= params.baseAmount && Tick.unwrap(tick) > type(int24).min) {\n if (params.limitPrice > tick.toPrice()) break;\n uint256 maxAmount;\n if (key.takerPolicy.usesQuote()) {\n maxAmount = params.baseAmount - spentBaseAmount;\n } else {\n maxAmount = key.takerPolicy.calculateOriginalAmount(params.baseAmount - spentBaseAmount, false);\n }\n maxAmount = tick.baseToQuote(maxAmount, false) / key.unitSize;\n\n if (maxAmount == 0) break;\n uint256 currentDepth = bookManager.getDepth(params.id, tick);\n uint256 quoteAmount = (currentDepth > maxAmount ? maxAmount : currentDepth) * key.unitSize;\n uint256 baseAmount = tick.quoteToBase(quoteAmount, true);\n if (key.takerPolicy.usesQuote()) {\n quoteAmount = uint256(int256(quoteAmount) - key.takerPolicy.calculateFee(quoteAmount, false));\n } else {\n baseAmount = uint256(baseAmount.toInt256() + key.takerPolicy.calculateFee(baseAmount, false));\n }\n if (baseAmount == 0) break;\n\n takenQuoteAmount += quoteAmount;\n spentBaseAmount += baseAmount;\n tick = bookManager.maxLessThan(params.id, tick);\n }\n }\n }\n}\n" + }, + "src/Controller.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.0;\n\nimport {IERC20Permit} from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {ILocker} from \"v2-core/interfaces/ILocker.sol\";\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\nimport {IERC721Permit} from \"v2-core/interfaces/IERC721Permit.sol\";\nimport {Math} from \"v2-core/libraries/Math.sol\";\nimport {BookId, BookIdLibrary} from \"v2-core/libraries/BookId.sol\";\nimport {OrderId, OrderIdLibrary} from \"v2-core/libraries/OrderId.sol\";\nimport {Currency, CurrencyLibrary} from \"v2-core/libraries/Currency.sol\";\nimport {FeePolicy, FeePolicyLibrary} from \"v2-core/libraries/FeePolicy.sol\";\nimport {Tick, TickLibrary} from \"v2-core/libraries/Tick.sol\";\nimport {OrderId, OrderIdLibrary} from \"v2-core/libraries/OrderId.sol\";\n\nimport {IController} from \"./interfaces/IController.sol\";\nimport {ReentrancyGuard} from \"./libraries/ReentrancyGuard.sol\";\n\ncontract Controller is IController, ILocker, ReentrancyGuard {\n using TickLibrary for *;\n using OrderIdLibrary for OrderId;\n using BookIdLibrary for IBookManager.BookKey;\n using SafeERC20 for IERC20;\n using SafeCast for uint256;\n using Math for uint256;\n using CurrencyLibrary for Currency;\n using FeePolicyLibrary for FeePolicy;\n\n IBookManager public immutable bookManager;\n\n constructor(address bookManager_) {\n bookManager = IBookManager(bookManager_);\n }\n\n modifier checkDeadline(uint64 deadline) {\n if (block.timestamp > deadline) revert Deadline();\n _;\n }\n\n modifier permitERC20(ERC20PermitParams[] calldata permitParamsList) {\n _permitERC20(permitParamsList);\n _;\n }\n\n function getDepth(BookId id, Tick tick) external view returns (uint256) {\n return uint256(bookManager.getDepth(id, tick)) * bookManager.getBookKey(id).unitSize;\n }\n\n function getHighestPrice(BookId id) external view returns (uint256) {\n return bookManager.getHighest(id).toPrice();\n }\n\n function getOrder(OrderId orderId)\n external\n view\n returns (address provider, uint256 price, uint256 openAmount, uint256 claimableAmount)\n {\n (BookId bookId, Tick tick,) = orderId.decode();\n IBookManager.BookKey memory key = bookManager.getBookKey(bookId);\n uint256 unitSize = key.unitSize;\n price = tick.toPrice();\n IBookManager.OrderInfo memory orderInfo = bookManager.getOrder(orderId);\n provider = orderInfo.provider;\n openAmount = unitSize * orderInfo.open;\n FeePolicy makerPolicy = key.makerPolicy;\n claimableAmount = tick.quoteToBase(unitSize * orderInfo.claimable, false);\n if (!makerPolicy.usesQuote()) {\n int256 fee = makerPolicy.calculateFee(claimableAmount, false);\n claimableAmount = fee > 0 ? claimableAmount - uint256(fee) : claimableAmount + uint256(-fee);\n }\n }\n\n function fromPrice(uint256 price) external pure returns (Tick) {\n return price.fromPrice();\n }\n\n function toPrice(Tick tick) external pure returns (uint256) {\n return tick.toPrice();\n }\n\n function lockAcquired(address sender, bytes memory data) external nonReentrant returns (bytes memory returnData) {\n if (msg.sender != address(bookManager) || sender != address(this)) revert InvalidAccess();\n (address user, Action[] memory actionList, bytes[] memory orderParamsList, address[] memory tokensToSettle) =\n abi.decode(data, (address, Action[], bytes[], address[]));\n\n uint256 length = actionList.length;\n OrderId[] memory ids = new OrderId[](length);\n uint256 orderIdIndex;\n\n for (uint256 i = 0; i < length; ++i) {\n Action action = actionList[i];\n if (action == Action.OPEN) {\n _open(abi.decode(orderParamsList[i], (OpenBookParams)));\n } else if (action == Action.MAKE) {\n OrderId id = _make(abi.decode(orderParamsList[i], (MakeOrderParams)));\n if (OrderId.unwrap(id) != 0) {\n bookManager.transferFrom(address(this), user, OrderId.unwrap(id));\n ids[orderIdIndex++] = id;\n }\n } else if (action == Action.LIMIT) {\n OrderId id = _limit(abi.decode(orderParamsList[i], (LimitOrderParams)));\n if (OrderId.unwrap(id) != 0) {\n bookManager.transferFrom(address(this), user, OrderId.unwrap(id));\n ids[orderIdIndex++] = id;\n }\n } else if (action == Action.TAKE) {\n _take(abi.decode(orderParamsList[i], (TakeOrderParams)));\n } else if (action == Action.SPEND) {\n _spend(abi.decode(orderParamsList[i], (SpendOrderParams)));\n } else if (action == Action.CLAIM) {\n ClaimOrderParams memory claimOrderParams = abi.decode(orderParamsList[i], (ClaimOrderParams));\n uint256 orderId = OrderId.unwrap(claimOrderParams.id);\n bookManager.checkAuthorized(bookManager.ownerOf(orderId), user, orderId);\n _claim(claimOrderParams);\n } else if (action == Action.CANCEL) {\n CancelOrderParams memory cancelOrderParams = abi.decode(orderParamsList[i], (CancelOrderParams));\n uint256 orderId = OrderId.unwrap(cancelOrderParams.id);\n bookManager.checkAuthorized(bookManager.ownerOf(orderId), user, orderId);\n _cancel(cancelOrderParams);\n } else {\n revert InvalidAction();\n }\n }\n\n _settleTokens(user, tokensToSettle);\n\n assembly {\n mstore(ids, orderIdIndex)\n }\n returnData = abi.encode(ids);\n }\n\n function execute(\n Action[] calldata actionList,\n bytes[] calldata paramsDataList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata erc20PermitParamsList,\n ERC721PermitParams[] calldata erc721PermitParamsList,\n uint64 deadline\n ) external payable checkDeadline(deadline) returns (OrderId[] memory ids) {\n if (actionList.length != paramsDataList.length) revert InvalidLength();\n _permitERC20(erc20PermitParamsList);\n _permitERC721(erc721PermitParamsList);\n\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bytes memory result = bookManager.lock(address(this), lockData);\n\n if (result.length != 0) {\n (ids) = abi.decode(result, (OrderId[]));\n }\n return ids;\n }\n\n function open(OpenBookParams[] calldata openBookParamsList, uint64 deadline) external checkDeadline(deadline) {\n uint256 length = openBookParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.OPEN;\n paramsDataList[i] = abi.encode(openBookParamsList[i]);\n }\n address[] memory tokensToSettle;\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bookManager.lock(address(this), lockData);\n }\n\n function limit(\n LimitOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable checkDeadline(deadline) permitERC20(permitParamsList) returns (OrderId[] memory ids) {\n uint256 length = orderParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.LIMIT;\n paramsDataList[i] = abi.encode(orderParamsList[i]);\n }\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bytes memory result = bookManager.lock(address(this), lockData);\n (ids) = abi.decode(result, (OrderId[]));\n }\n\n function make(\n MakeOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable checkDeadline(deadline) permitERC20(permitParamsList) returns (OrderId[] memory ids) {\n uint256 length = orderParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.MAKE;\n paramsDataList[i] = abi.encode(orderParamsList[i]);\n }\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bytes memory result = bookManager.lock(address(this), lockData);\n (ids) = abi.decode(result, (OrderId[]));\n }\n\n function take(\n TakeOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable checkDeadline(deadline) permitERC20(permitParamsList) {\n uint256 length = orderParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.TAKE;\n paramsDataList[i] = abi.encode(orderParamsList[i]);\n }\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bookManager.lock(address(this), lockData);\n }\n\n function spend(\n SpendOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable checkDeadline(deadline) permitERC20(permitParamsList) {\n uint256 length = orderParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.SPEND;\n paramsDataList[i] = abi.encode(orderParamsList[i]);\n }\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bookManager.lock(address(this), lockData);\n }\n\n function claim(\n ClaimOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC721PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external checkDeadline(deadline) {\n _permitERC721(permitParamsList);\n uint256 length = orderParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.CLAIM;\n paramsDataList[i] = abi.encode(orderParamsList[i]);\n }\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bookManager.lock(address(this), lockData);\n }\n\n function cancel(\n CancelOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC721PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external checkDeadline(deadline) {\n _permitERC721(permitParamsList);\n uint256 length = orderParamsList.length;\n Action[] memory actionList = new Action[](length);\n bytes[] memory paramsDataList = new bytes[](length);\n for (uint256 i = 0; i < length; ++i) {\n actionList[i] = Action.CANCEL;\n paramsDataList[i] = abi.encode(orderParamsList[i]);\n }\n bytes memory lockData = abi.encode(msg.sender, actionList, paramsDataList, tokensToSettle);\n bookManager.lock(address(this), lockData);\n }\n\n function _open(OpenBookParams memory params) internal {\n bookManager.open(params.key, params.hookData);\n }\n\n function _make(MakeOrderParams memory params) internal returns (OrderId id) {\n IBookManager.BookKey memory key = bookManager.getBookKey(params.id);\n\n uint256 quoteAmount = params.quoteAmount;\n if (key.makerPolicy.usesQuote()) {\n quoteAmount = key.makerPolicy.calculateOriginalAmount(quoteAmount, false);\n }\n uint64 unit = (quoteAmount / key.unitSize).toUint64();\n if (unit > 0) {\n (id,) = bookManager.make(\n IBookManager.MakeParams({key: key, tick: params.tick, unit: unit, provider: address(0)}),\n params.hookData\n );\n }\n return id;\n }\n\n function _limit(LimitOrderParams memory params) internal returns (OrderId id) {\n (, uint256 spentBaseAmount) = _spend(\n SpendOrderParams({\n id: params.takeBookId,\n limitPrice: params.limitPrice,\n baseAmount: params.quoteAmount,\n minQuoteAmount: 0,\n hookData: params.takeHookData\n })\n );\n params.quoteAmount -= spentBaseAmount;\n if (params.quoteAmount > 0) {\n id = _make(\n MakeOrderParams({\n id: params.makeBookId,\n quoteAmount: params.quoteAmount,\n tick: params.tick,\n hookData: params.makeHookData\n })\n );\n }\n }\n\n function _take(TakeOrderParams memory params)\n internal\n returns (uint256 takenQuoteAmount, uint256 spentBaseAmount)\n {\n IBookManager.BookKey memory key = bookManager.getBookKey(params.id);\n\n while (params.quoteAmount > takenQuoteAmount && !bookManager.isEmpty(params.id)) {\n Tick tick = bookManager.getHighest(params.id);\n if (params.limitPrice > tick.toPrice()) break;\n uint256 maxAmount;\n unchecked {\n if (key.takerPolicy.usesQuote()) {\n maxAmount = key.takerPolicy.calculateOriginalAmount(params.quoteAmount - takenQuoteAmount, true);\n } else {\n maxAmount = params.quoteAmount - takenQuoteAmount;\n }\n }\n maxAmount = maxAmount.divide(key.unitSize, true);\n\n if (maxAmount == 0) break;\n (uint256 quoteAmount, uint256 baseAmount) = bookManager.take(\n IBookManager.TakeParams({key: key, tick: tick, maxUnit: maxAmount.toUint64()}), params.hookData\n );\n if (quoteAmount == 0) break;\n\n takenQuoteAmount += quoteAmount;\n spentBaseAmount += baseAmount;\n }\n if (params.maxBaseAmount < spentBaseAmount) revert ControllerSlippage();\n }\n\n function _spend(SpendOrderParams memory params)\n internal\n returns (uint256 takenQuoteAmount, uint256 spentBaseAmount)\n {\n IBookManager.BookKey memory key = bookManager.getBookKey(params.id);\n\n while (spentBaseAmount < params.baseAmount && !bookManager.isEmpty(params.id)) {\n Tick tick = bookManager.getHighest(params.id);\n if (params.limitPrice > tick.toPrice()) break;\n uint256 maxAmount;\n unchecked {\n if (key.takerPolicy.usesQuote()) {\n maxAmount = params.baseAmount - spentBaseAmount;\n } else {\n maxAmount = key.takerPolicy.calculateOriginalAmount(params.baseAmount - spentBaseAmount, false);\n }\n }\n maxAmount = tick.baseToQuote(maxAmount, false) / key.unitSize;\n if (maxAmount == 0) break;\n (uint256 quoteAmount, uint256 baseAmount) = bookManager.take(\n IBookManager.TakeParams({key: key, tick: tick, maxUnit: maxAmount.toUint64()}), params.hookData\n );\n if (baseAmount == 0) break;\n takenQuoteAmount += quoteAmount;\n spentBaseAmount += baseAmount;\n }\n if (params.minQuoteAmount > takenQuoteAmount) revert ControllerSlippage();\n }\n\n function _claim(ClaimOrderParams memory params) internal {\n bookManager.claim(params.id, params.hookData);\n }\n\n function _cancel(CancelOrderParams memory params) internal {\n IBookManager.BookKey memory key = bookManager.getBookKey(params.id.getBookId());\n try bookManager.cancel(\n IBookManager.CancelParams({id: params.id, toUnit: (params.leftQuoteAmount / key.unitSize).toUint64()}),\n params.hookData\n ) {} catch {}\n }\n\n function _settleTokens(address user, address[] memory tokensToSettle) internal {\n Currency native = CurrencyLibrary.NATIVE;\n int256 currencyDelta = bookManager.getCurrencyDelta(address(this), native);\n if (currencyDelta < 0) {\n native.transfer(address(bookManager), uint256(-currencyDelta));\n bookManager.settle(native);\n }\n currencyDelta = bookManager.getCurrencyDelta(address(this), native);\n if (currencyDelta > 0) {\n bookManager.withdraw(native, user, uint256(currencyDelta));\n }\n\n uint256 length = tokensToSettle.length;\n for (uint256 i = 0; i < length; ++i) {\n Currency currency = Currency.wrap(tokensToSettle[i]);\n currencyDelta = bookManager.getCurrencyDelta(address(this), currency);\n if (currencyDelta < 0) {\n IERC20(tokensToSettle[i]).safeTransferFrom(user, address(bookManager), uint256(-currencyDelta));\n bookManager.settle(currency);\n }\n currencyDelta = bookManager.getCurrencyDelta(address(this), currency);\n if (currencyDelta > 0) {\n bookManager.withdraw(Currency.wrap(tokensToSettle[i]), user, uint256(currencyDelta));\n }\n uint256 balance = IERC20(tokensToSettle[i]).balanceOf(address(this));\n if (balance > 0) {\n IERC20(tokensToSettle[i]).transfer(user, balance);\n }\n }\n if (address(this).balance > 0) native.transfer(user, address(this).balance);\n }\n\n function _permitERC20(ERC20PermitParams[] calldata permitParamsList) internal {\n for (uint256 i = 0; i < permitParamsList.length; ++i) {\n ERC20PermitParams memory permitParams = permitParamsList[i];\n if (permitParams.signature.deadline > 0) {\n try IERC20Permit(permitParams.token).permit(\n msg.sender,\n address(this),\n permitParams.permitAmount,\n permitParams.signature.deadline,\n permitParams.signature.v,\n permitParams.signature.r,\n permitParams.signature.s\n ) {} catch {}\n }\n }\n }\n\n function _permitERC721(ERC721PermitParams[] calldata permitParamsList) internal {\n for (uint256 i = 0; i < permitParamsList.length; ++i) {\n PermitSignature memory signature = permitParamsList[i].signature;\n if (signature.deadline > 0) {\n try IERC721Permit(address(bookManager)).permit(\n address(this),\n permitParamsList[i].tokenId,\n signature.deadline,\n signature.v,\n signature.r,\n signature.s\n ) {} catch {}\n }\n }\n }\n\n receive() external payable {}\n}\n" + }, + "src/interfaces/IArbitrage.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {BookId} from \"v2-core/libraries/BookId.sol\";\nimport {Currency} from \"v2-core/libraries/Currency.sol\";\n\ninterface IArbitrage {\n error InvalidAccess();\n error NotOperator();\n\n event SetOperator(address indexed operator, bool status);\n\n function setOperator(address operator, bool status) external;\n\n function arbitrage(BookId id, address router, bytes calldata data) external;\n\n function withdrawToken(Currency currency, uint256 amount, address recipient) external;\n}\n" + }, + "src/interfaces/IBookViewer.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {BookId} from \"v2-core/libraries/BookId.sol\";\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\nimport {Tick} from \"v2-core/libraries/Tick.sol\";\n\nimport {IController} from \"./IController.sol\";\n\n/**\n * @title IBookViewer\n * @notice Interface for the book viewer contract\n */\ninterface IBookViewer {\n struct Liquidity {\n Tick tick;\n uint64 depth;\n }\n\n /**\n * @notice Returns the book manager\n * @return The instance of the book manager\n */\n function bookManager() external view returns (IBookManager);\n\n /**\n * @notice Returns the liquidity for a specific book\n * @param id The id of the book\n * @param from The starting tick\n * @param n The number of ticks to return\n * @return liquidity An array of liquidity data\n */\n function getLiquidity(BookId id, Tick from, uint256 n) external view returns (Liquidity[] memory liquidity);\n\n /**\n * @notice Returns the expected input for a take order\n * @param params The parameters of the take order\n * @return takenQuoteAmount The expected taken quote amount\n * @return spentBaseAmount The expected spend base amount\n */\n function getExpectedInput(IController.TakeOrderParams memory params)\n external\n view\n returns (uint256 takenQuoteAmount, uint256 spentBaseAmount);\n\n /**\n * @notice Returns the expected output for a spend order\n * @param params The parameters of the spend order\n * @return takenQuoteAmount The expected taken quote amount\n * @return spentBaseAmount The expected spend base amount\n */\n function getExpectedOutput(IController.SpendOrderParams memory params)\n external\n view\n returns (uint256 takenQuoteAmount, uint256 spentBaseAmount);\n}\n" + }, + "src/interfaces/IController.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {OrderId} from \"v2-core/libraries/OrderId.sol\";\nimport {BookId} from \"v2-core/libraries/BookId.sol\";\nimport {Tick} from \"v2-core/libraries/Tick.sol\";\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\n\n/**\n * @title IController\n * @notice Interface for the controller contract\n */\ninterface IController {\n // Error messages\n error InvalidAccess();\n error InvalidLength();\n error Deadline();\n error ControllerSlippage();\n error InvalidAction();\n\n /**\n * @notice Enum for the different actions that can be performed\n */\n enum Action {\n OPEN,\n MAKE,\n LIMIT,\n TAKE,\n SPEND,\n CLAIM,\n CANCEL\n }\n\n /**\n * @notice Struct for the parameters of the ERC20 permit\n */\n struct ERC20PermitParams {\n address token;\n uint256 permitAmount;\n PermitSignature signature;\n }\n\n /**\n * @notice Struct for the parameters of the ERC721 permit\n */\n struct ERC721PermitParams {\n uint256 tokenId;\n PermitSignature signature;\n }\n\n /**\n * @notice Struct for the signature of the permit\n */\n struct PermitSignature {\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n /**\n * @notice Struct for the parameters of the open book action\n */\n struct OpenBookParams {\n IBookManager.BookKey key;\n bytes hookData;\n }\n\n /**\n * @notice Struct for the parameters of the make order action\n */\n struct MakeOrderParams {\n BookId id;\n Tick tick;\n uint256 quoteAmount;\n bytes hookData;\n }\n\n /**\n * @notice Struct for the parameters of the limit order action\n */\n struct LimitOrderParams {\n BookId takeBookId;\n BookId makeBookId;\n uint256 limitPrice;\n Tick tick;\n uint256 quoteAmount;\n bytes takeHookData;\n bytes makeHookData;\n }\n\n /**\n * @notice Struct for the parameters of the take order action\n */\n struct TakeOrderParams {\n BookId id;\n uint256 limitPrice;\n uint256 quoteAmount;\n uint256 maxBaseAmount;\n bytes hookData;\n }\n\n /**\n * @notice Struct for the parameters of the spend order action\n */\n struct SpendOrderParams {\n BookId id;\n uint256 limitPrice;\n uint256 baseAmount;\n uint256 minQuoteAmount;\n bytes hookData;\n }\n\n /**\n * @notice Struct for the parameters of the claim order action\n */\n struct ClaimOrderParams {\n OrderId id;\n bytes hookData;\n }\n\n /**\n * @notice Struct for the parameters of the cancel order action\n */\n struct CancelOrderParams {\n OrderId id;\n uint256 leftQuoteAmount;\n bytes hookData;\n }\n\n /**\n * @notice Returns the book manager\n * @return The instance of the book manager\n */\n function bookManager() external view returns (IBookManager);\n\n /**\n * @notice Opens a book\n * @param openBookParamsList The parameters of the open book action\n * @param deadline The deadline for the action\n */\n function open(OpenBookParams[] calldata openBookParamsList, uint64 deadline) external;\n\n /**\n * @notice Returns the depth of a book\n * @param id The id of the book\n * @param tick The tick of the book\n * @return The depth of the book in quote amount\n */\n function getDepth(BookId id, Tick tick) external view returns (uint256);\n\n /**\n * @notice Returns the highest price of a book\n * @param id The id of the book\n * @return The highest price of the book with 2**96 precision\n */\n function getHighestPrice(BookId id) external view returns (uint256);\n\n /**\n * @notice Returns the details of an order\n * @param orderId The id of the order\n * @return provider The provider of the order\n * @return price The price of the order with 2**96 precision\n * @return openAmount The open quote amount of the order\n * @return claimableAmount The claimable base amount of the order\n */\n function getOrder(OrderId orderId)\n external\n view\n returns (address provider, uint256 price, uint256 openAmount, uint256 claimableAmount);\n\n /**\n * @notice Converts a price to a tick\n * @param price The price to convert\n * @return The tick\n */\n function fromPrice(uint256 price) external pure returns (Tick);\n\n /**\n * @notice Converts a tick to a price\n * @param tick The tick to convert\n * @return The price with 2**96 precision\n */\n function toPrice(Tick tick) external pure returns (uint256);\n\n /**\n * @notice Executes a list of actions\n * @dev IMPORTANT: The caller must provide `tokensToSettle` to receive appropriate tokens after execution.\n * @param actionList The list of actions to execute\n * @param paramsDataList The parameters of the actions\n * @param tokensToSettle The tokens to settle\n * @param erc20PermitParamsList The parameters of the ERC20 permits\n * @param erc721PermitParamsList The parameters of the ERC721 permits\n * @param deadline The deadline for the actions\n * @return ids The ids of the orders\n */\n function execute(\n Action[] calldata actionList,\n bytes[] calldata paramsDataList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata erc20PermitParamsList,\n ERC721PermitParams[] calldata erc721PermitParamsList,\n uint64 deadline\n ) external payable returns (OrderId[] memory ids);\n\n /**\n * @notice Makes a list of orders\n * @dev IMPORTANT: The caller must provide `tokensToSettle` to receive appropriate tokens after execution.\n * @param orderParamsList The list of actions to make\n * @param tokensToSettle The tokens to settle\n * @param permitParamsList The parameters of the permits\n * @param deadline The deadline for the actions\n * @return ids The ids of the orders\n */\n function make(\n MakeOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable returns (OrderId[] memory ids);\n\n /**\n * @notice Takes a list of orders\n * @dev IMPORTANT: The caller must provide `tokensToSettle` to receive appropriate tokens after execution.\n * @param orderParamsList The list of actions to take\n * @param tokensToSettle The tokens to settle\n * @param permitParamsList The parameters of the permits\n * @param deadline The deadline for the actions\n */\n function take(\n TakeOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable;\n\n /**\n * @notice Spends to take a list of orders\n * @dev IMPORTANT: The caller must provide `tokensToSettle` to receive appropriate tokens after execution.\n * @param orderParamsList The list of actions to spend\n * @param tokensToSettle The tokens to settle\n * @param permitParamsList The parameters of the permits\n * @param deadline The deadline for the actions\n */\n function spend(\n SpendOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC20PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external payable;\n\n /**\n * @notice Claims a list of orders\n * @dev IMPORTANT: The caller must provide `tokensToSettle` to receive appropriate tokens after execution.\n * @param orderParamsList The list of actions to claim\n * @param tokensToSettle The tokens to settle\n * @param permitParamsList The parameters of the permits\n * @param deadline The deadline for the actions\n */\n function claim(\n ClaimOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC721PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external;\n\n /**\n * @notice Cancels a list of orders\n * @dev IMPORTANT: The caller must provide `tokensToSettle` to receive appropriate tokens after execution.\n * @param orderParamsList The list of actions to cancel\n * @param tokensToSettle The tokens to settle\n * @param permitParamsList The parameters of the permits\n * @param deadline The deadline for the actions\n */\n function cancel(\n CancelOrderParams[] calldata orderParamsList,\n address[] calldata tokensToSettle,\n ERC721PermitParams[] calldata permitParamsList,\n uint64 deadline\n ) external;\n}\n" + }, + "src/interfaces/IProvider.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {Currency, CurrencyLibrary} from \"v2-core/libraries/Currency.sol\";\nimport {IProviderFactory} from \"./IProviderFactory.sol\";\n\ninterface IProvider {\n event Claim(\n address indexed broker,\n address indexed protocolTreasury,\n Currency indexed currency,\n uint256 brokerShare,\n uint256 protocolShare\n );\n\n function factory() external returns (IProviderFactory);\n\n function broker() external returns (address);\n\n function shareRatio() external returns (uint256);\n\n function claim(Currency[] calldata currencies) external;\n}\n" + }, + "src/interfaces/IProviderFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\n\ninterface IProviderFactory {\n event DeployProvider(address indexed provider, address indexed broker, uint256 shareRatio);\n\n event SetTreasury(address indexed treasury);\n\n function bookManager() external returns (IBookManager);\n\n function treasury() external returns (address);\n\n function deployProvider(address broker) external returns (address);\n\n function deployProvider(address broker, uint256 shareRatio) external returns (address);\n\n function setTreasury(address newTreasury) external;\n\n /**\n * @notice Whitelists a provider\n * @param provider The provider address\n */\n function whitelist(address provider) external;\n\n /**\n * @notice Delists a provider\n * @param provider The provider address\n */\n function delist(address provider) external;\n\n /**\n * @notice Sets the default provider\n * @param newDefaultProvider The new default provider address\n */\n function setDefaultProvider(address newDefaultProvider) external;\n\n function transferBookManagerOwnership(address newOwner) external;\n}\n" + }, + "src/libraries/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.24;\n\nabstract contract ReentrancyGuard {\n // uint256(keccak256(\"ReentrancyGuard\")) - 1\n uint256 internal constant REENTRANCY_GUARD_SLOT = 0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4;\n\n error ReentrancyGuardReentrantCall();\n\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n if (_reentrancyGuardEntered()) {\n revert ReentrancyGuardReentrantCall();\n }\n assembly {\n // Any calls to nonReentrant after this point will fail\n tstore(REENTRANCY_GUARD_SLOT, 1)\n }\n }\n\n function _nonReentrantAfter() private {\n assembly {\n tstore(REENTRANCY_GUARD_SLOT, 0)\n }\n }\n\n function _reentrancyGuardEntered() internal view returns (bool isEntered) {\n assembly {\n isEntered := tload(REENTRANCY_GUARD_SLOT)\n }\n }\n}\n" + }, + "src/Provider.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\nimport {Currency, CurrencyLibrary} from \"v2-core/libraries/Currency.sol\";\nimport {IProvider} from \"./interfaces/IProvider.sol\";\nimport {IProviderFactory} from \"./interfaces/IProviderFactory.sol\";\n\ncontract Provider is IProvider {\n using CurrencyLibrary for Currency;\n\n uint256 public constant RATE_PRECISION = 10 ** 6;\n\n IBookManager private immutable _bookManager;\n IProviderFactory public immutable factory;\n address public immutable broker;\n uint256 public immutable shareRatio;\n\n constructor(address broker_, uint256 shareRatio_) {\n factory = IProviderFactory(msg.sender);\n _bookManager = factory.bookManager();\n broker = broker_;\n shareRatio = shareRatio_;\n }\n\n function claim(Currency[] calldata currencies) external {\n address protocolTreasury = factory.treasury();\n for (uint256 i = 0; i < currencies.length; ++i) {\n Currency currency = currencies[i];\n _bookManager.collect(address(this), currency);\n uint256 balance = currency.balanceOfSelf();\n uint256 brokerShare = balance * shareRatio / RATE_PRECISION;\n uint256 protocolShare = balance - brokerShare;\n currency.transfer(broker, brokerShare);\n currency.transfer(protocolTreasury, protocolShare);\n emit Claim(broker, protocolTreasury, currency, brokerShare, protocolShare);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "src/ProviderFactory.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {Ownable2Step, Ownable} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport {IProviderFactory} from \"./interfaces/IProviderFactory.sol\";\nimport {IBookManager} from \"v2-core/interfaces/IBookManager.sol\";\nimport {Provider} from \"./Provider.sol\";\n\ncontract ProviderFactory is IProviderFactory, UUPSUpgradeable, Ownable2Step, Initializable {\n uint256 public defaultBrokerShareRatio;\n IBookManager public bookManager;\n address public treasury;\n\n constructor() Ownable(msg.sender) {}\n\n function __ProviderFactory_init(\n address owner_,\n address bookManager_,\n address treasury_,\n uint256 defaultBrokerShareRatio_\n ) public initializer {\n _transferOwnership(owner_);\n Ownable2Step(bookManager_).acceptOwnership();\n bookManager = IBookManager(bookManager_);\n treasury = treasury_;\n defaultBrokerShareRatio = defaultBrokerShareRatio_;\n }\n\n function _authorizeUpgrade(address) internal override onlyOwner {}\n\n function deployProvider(address broker) external returns (address) {\n return _deployProvider(broker, defaultBrokerShareRatio);\n }\n\n function deployProvider(address broker, uint256 shareRatio) public onlyOwner returns (address) {\n return _deployProvider(broker, shareRatio);\n }\n\n function _deployProvider(address broker, uint256 shareRatio) internal returns (address provider) {\n provider = address(new Provider(broker, shareRatio));\n bookManager.whitelist(provider);\n emit DeployProvider(provider, broker, shareRatio);\n }\n\n function setTreasury(address newTreasury) external onlyOwner {\n treasury = newTreasury;\n emit SetTreasury(newTreasury);\n }\n\n function whitelist(address provider) external onlyOwner {\n bookManager.whitelist(provider);\n }\n\n function delist(address provider) external onlyOwner {\n bookManager.delist(provider);\n }\n\n function setDefaultProvider(address newDefaultProvider) external onlyOwner {\n bookManager.setDefaultProvider(newDefaultProvider);\n }\n\n function transferBookManagerOwnership(address newOwner) external onlyOwner {\n Ownable2Step(address(bookManager)).transferOwnership(newOwner);\n }\n}\n" + }, + "v2-core/interfaces/IBookManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\n\nimport {BookId} from \"../libraries/BookId.sol\";\nimport {Currency} from \"../libraries/Currency.sol\";\nimport {OrderId} from \"../libraries/OrderId.sol\";\nimport {Tick} from \"../libraries/Tick.sol\";\nimport {FeePolicy} from \"../libraries/FeePolicy.sol\";\nimport {IERC721Permit} from \"./IERC721Permit.sol\";\nimport {IHooks} from \"./IHooks.sol\";\n\n/**\n * @title IBookManager\n * @notice The interface for the BookManager contract\n */\ninterface IBookManager is IERC721Metadata, IERC721Permit {\n error InvalidUnitSize();\n error InvalidFeePolicy();\n error InvalidProvider(address provider);\n error LockedBy(address locker, address hook);\n error CurrencyNotSettled();\n\n /**\n * @notice Event emitted when a new book is opened\n * @param id The book id\n * @param base The base currency\n * @param quote The quote currency\n * @param unitSize The unit size of the book\n * @param makerPolicy The maker fee policy\n * @param takerPolicy The taker fee policy\n * @param hooks The hooks contract\n */\n event Open(\n BookId indexed id,\n Currency indexed base,\n Currency indexed quote,\n uint64 unitSize,\n FeePolicy makerPolicy,\n FeePolicy takerPolicy,\n IHooks hooks\n );\n\n /**\n * @notice Event emitted when a new order is made\n * @param bookId The book id\n * @param user The user address\n * @param tick The order tick\n * @param orderIndex The order index\n * @param unit The order unit\n * @param provider The provider address\n */\n event Make(\n BookId indexed bookId, address indexed user, Tick tick, uint256 orderIndex, uint64 unit, address provider\n );\n\n /**\n * @notice Event emitted when an order is taken\n * @param bookId The book id\n * @param user The user address\n * @param tick The order tick\n * @param unit The order unit\n */\n event Take(BookId indexed bookId, address indexed user, Tick tick, uint64 unit);\n\n /**\n * @notice Event emitted when an order is canceled\n * @param orderId The order id\n * @param unit The canceled unit\n */\n event Cancel(OrderId indexed orderId, uint64 unit);\n\n /**\n * @notice Event emitted when an order is claimed\n * @param orderId The order id\n * @param unit The claimed unit\n */\n event Claim(OrderId indexed orderId, uint64 unit);\n\n /**\n * @notice Event emitted when a provider is whitelisted\n * @param provider The provider address\n */\n event Whitelist(address indexed provider);\n\n /**\n * @notice Event emitted when a provider is delisted\n * @param provider The provider address\n */\n event Delist(address indexed provider);\n\n /**\n * @notice Event emitted when a provider collects fees\n * @param provider The provider address\n * @param recipient The recipient address\n * @param currency The currency\n * @param amount The collected amount\n */\n event Collect(address indexed provider, address indexed recipient, Currency indexed currency, uint256 amount);\n\n /**\n * @notice Event emitted when new default provider is set\n * @param newDefaultProvider The new default provider address\n */\n event SetDefaultProvider(address indexed newDefaultProvider);\n\n /**\n * @notice This structure represents a unique identifier for a book in the BookManager.\n * @param base The base currency of the book\n * @param unitSize The unit size of the book\n * @param quote The quote currency of the book\n * @param makerPolicy The maker fee policy of the book\n * @param hooks The hooks contract of the book\n * @param takerPolicy The taker fee policy of the book\n */\n struct BookKey {\n Currency base;\n uint64 unitSize;\n Currency quote;\n FeePolicy makerPolicy;\n IHooks hooks;\n FeePolicy takerPolicy;\n }\n\n /**\n * @notice Returns the base URI\n * @return The base URI\n */\n function baseURI() external view returns (string memory);\n\n /**\n * @notice Returns the contract URI\n * @return The contract URI\n */\n function contractURI() external view returns (string memory);\n\n /**\n * @notice Returns the default provider\n * @return The default provider\n */\n function defaultProvider() external view returns (address);\n\n /**\n * @notice Returns the total reserves of a given currency\n * @param currency The currency in question\n * @return The total reserves amount\n */\n function reservesOf(Currency currency) external view returns (uint256);\n\n /**\n * @notice Checks if a provider is whitelisted\n * @param provider The address of the provider\n * @return True if the provider is whitelisted, false otherwise\n */\n function isWhitelisted(address provider) external view returns (bool);\n\n /**\n * @notice Verifies if an owner has authorized a spender for a token\n * @param owner The address of the token owner\n * @param spender The address of the spender\n * @param tokenId The token ID\n */\n function checkAuthorized(address owner, address spender, uint256 tokenId) external view;\n\n /**\n * @notice Calculates the amount owed to a provider in a given currency\n * @param provider The provider's address\n * @param currency The currency in question\n * @return The owed amount\n */\n function tokenOwed(address provider, Currency currency) external view returns (uint256);\n\n /**\n * @notice Calculates the currency balance changes for a given locker\n * @param locker The address of the locker\n * @param currency The currency in question\n * @return The net change in currency balance\n */\n function getCurrencyDelta(address locker, Currency currency) external view returns (int256);\n\n /**\n * @notice Retrieves the book key for a given book ID\n * @param id The book ID\n * @return The book key\n */\n function getBookKey(BookId id) external view returns (BookKey memory);\n\n /**\n * @notice This structure represents a current status for an order in the BookManager.\n * @param provider The provider of the order\n * @param open The open unit of the order\n * @param claimable The claimable unit of the order\n */\n struct OrderInfo {\n address provider;\n uint64 open;\n uint64 claimable;\n }\n\n /**\n * @notice Provides information about an order\n * @param id The order ID\n * @return Order information including provider, open status, and claimable unit\n */\n function getOrder(OrderId id) external view returns (OrderInfo memory);\n\n /**\n * @notice Retrieves the locker and caller addresses for a given lock\n * @param i The index of the lock\n * @return locker The locker's address\n * @return lockCaller The caller's address\n */\n function getLock(uint256 i) external view returns (address locker, address lockCaller);\n\n /**\n * @notice Provides the lock data\n * @return The lock data including necessary numeric values\n */\n function getLockData() external view returns (uint128, uint128);\n\n /**\n * @notice Returns the depth of a given book ID and tick\n * @param id The book ID\n * @param tick The tick\n * @return The depth of the tick\n */\n function getDepth(BookId id, Tick tick) external view returns (uint64);\n\n /**\n * @notice Retrieves the highest tick for a given book ID\n * @param id The book ID\n * @return tick The highest tick\n */\n function getHighest(BookId id) external view returns (Tick tick);\n\n /**\n * @notice Finds the maximum tick less than a specified tick in a book\n * @dev Returns `Tick.wrap(type(int24).min)` if the specified tick is the lowest\n * @param id The book ID\n * @param tick The specified tick\n * @return The next lower tick\n */\n function maxLessThan(BookId id, Tick tick) external view returns (Tick);\n\n /**\n * @notice Checks if a book is opened\n * @param id The book ID\n * @return True if the book is opened, false otherwise\n */\n function isOpened(BookId id) external view returns (bool);\n\n /**\n * @notice Checks if a book is empty\n * @param id The book ID\n * @return True if the book is empty, false otherwise\n */\n function isEmpty(BookId id) external view returns (bool);\n\n /**\n * @notice Encodes a BookKey into a BookId\n * @param key The BookKey to encode\n * @return The encoded BookId\n */\n function encodeBookKey(BookKey calldata key) external pure returns (BookId);\n\n /**\n * @notice Loads a value from a specific storage slot\n * @param slot The storage slot\n * @return The value in the slot\n */\n function load(bytes32 slot) external view returns (bytes32);\n\n /**\n * @notice Loads a sequence of values starting from a specific slot\n * @param startSlot The starting slot\n * @param nSlot The number of slots to load\n * @return The sequence of values\n */\n function load(bytes32 startSlot, uint256 nSlot) external view returns (bytes memory);\n\n /**\n * @notice Opens a new book\n * @param key The book key\n * @param hookData The hook data\n */\n function open(BookKey calldata key, bytes calldata hookData) external;\n\n /**\n * @notice Locks a book manager function\n * @param locker The locker address\n * @param data The lock data\n * @return The lock return data\n */\n function lock(address locker, bytes calldata data) external returns (bytes memory);\n\n /**\n * @notice This structure represents the parameters for making an order.\n * @param key The book key for the order\n * @param tick The tick for the order\n * @param unit The unit for the order. Times key.unitSize to get actual bid amount.\n * @param provider The provider for the order. The limit order service provider address to collect fees.\n */\n struct MakeParams {\n BookKey key;\n Tick tick;\n uint64 unit;\n address provider;\n }\n\n /**\n * @notice Make a limit order\n * @param params The order parameters\n * @param hookData The hook data\n * @return id The order id. Returns 0 if the order is not settled\n * @return quoteAmount The amount of quote currency to be paid\n */\n function make(MakeParams calldata params, bytes calldata hookData)\n external\n returns (OrderId id, uint256 quoteAmount);\n\n /**\n * @notice This structure represents the parameters for taking orders in the specified tick.\n * @param key The book key for the order\n * @param tick The tick for the order\n * @param maxUnit The max unit to take\n */\n struct TakeParams {\n BookKey key;\n Tick tick;\n uint64 maxUnit;\n }\n\n /**\n * @notice Take a limit order at specific tick\n * @param params The order parameters\n * @param hookData The hook data\n * @return quoteAmount The amount of quote currency to be received\n * @return baseAmount The amount of base currency to be paid\n */\n function take(TakeParams calldata params, bytes calldata hookData)\n external\n returns (uint256 quoteAmount, uint256 baseAmount);\n\n /**\n * @notice This structure represents the parameters for canceling an order.\n * @param id The order id for the order\n * @param toUnit The remaining open unit for the order after cancellation. Must not exceed the current open unit.\n */\n struct CancelParams {\n OrderId id;\n uint64 toUnit;\n }\n\n /**\n * @notice Cancel a limit order\n * @param params The order parameters\n * @param hookData The hook data\n * @return canceledAmount The amount of quote currency canceled\n */\n function cancel(CancelParams calldata params, bytes calldata hookData) external returns (uint256 canceledAmount);\n\n /**\n * @notice Claims an order\n * @param id The order ID\n * @param hookData The hook data\n * @return claimedAmount The amount claimed\n */\n function claim(OrderId id, bytes calldata hookData) external returns (uint256 claimedAmount);\n\n /**\n * @notice Collects fees from a provider\n * @param recipient The recipient address\n * @param currency The currency\n * @return The collected amount\n */\n function collect(address recipient, Currency currency) external returns (uint256);\n\n /**\n * @notice Withdraws a currency\n * @param currency The currency\n * @param to The recipient address\n * @param amount The amount\n */\n function withdraw(Currency currency, address to, uint256 amount) external;\n\n /**\n * @notice Settles a currency\n * @param currency The currency\n * @return The settled amount\n */\n function settle(Currency currency) external payable returns (uint256);\n\n /**\n * @notice Whitelists a provider\n * @param provider The provider address\n */\n function whitelist(address provider) external;\n\n /**\n * @notice Delists a provider\n * @param provider The provider address\n */\n function delist(address provider) external;\n\n /**\n * @notice Sets the default provider\n * @param newDefaultProvider The new default provider address\n */\n function setDefaultProvider(address newDefaultProvider) external;\n}\n" + }, + "v2-core/interfaces/IERC721Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\n/**\n * @title IERC721Permit\n * @notice An interface for the ERC721 permit extension\n */\ninterface IERC721Permit is IERC721 {\n error InvalidSignature();\n error PermitExpired();\n\n /**\n * @notice The EIP-712 typehash for the permit struct used by the contract\n */\n function PERMIT_TYPEHASH() external pure returns (bytes32);\n\n /**\n * @notice The EIP-712 domain separator for this contract\n */\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n /**\n * @notice Approve the spender to transfer the given tokenId\n * @param spender The address to approve\n * @param tokenId The tokenId to approve\n * @param deadline The deadline for the signature\n * @param v The recovery id of the signature\n * @param r The r value of the signature\n * @param s The s value of the signature\n */\n function permit(address spender, uint256 tokenId, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @notice Get the current nonce for a token\n * @param tokenId The tokenId to get the nonce for\n * @return The current nonce\n */\n function nonces(uint256 tokenId) external view returns (uint256);\n}\n" + }, + "v2-core/interfaces/IHooks.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport {IBookManager} from \"./IBookManager.sol\";\nimport {OrderId} from \"../libraries/OrderId.sol\";\n\n/**\n * @title IHooks\n * @notice Interface for the hooks contract\n */\ninterface IHooks {\n /**\n * @notice Hook called before opening a new book\n * @param sender The sender of the open transaction\n * @param key The key of the book being opened\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function beforeOpen(address sender, IBookManager.BookKey calldata key, bytes calldata hookData)\n external\n returns (bytes4);\n\n /**\n * @notice Hook called after opening a new book\n * @param sender The sender of the open transaction\n * @param key The key of the book being opened\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function afterOpen(address sender, IBookManager.BookKey calldata key, bytes calldata hookData)\n external\n returns (bytes4);\n\n /**\n * @notice Hook called before making a new order\n * @param sender The sender of the make transaction\n * @param params The parameters of the make transaction\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function beforeMake(address sender, IBookManager.MakeParams calldata params, bytes calldata hookData)\n external\n returns (bytes4);\n\n /**\n * @notice Hook called after making a new order\n * @param sender The sender of the make transaction\n * @param params The parameters of the make transaction\n * @param orderId The id of the order that was made\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function afterMake(\n address sender,\n IBookManager.MakeParams calldata params,\n OrderId orderId,\n bytes calldata hookData\n ) external returns (bytes4);\n\n /**\n * @notice Hook called before taking an order\n * @param sender The sender of the take transaction\n * @param params The parameters of the take transaction\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function beforeTake(address sender, IBookManager.TakeParams calldata params, bytes calldata hookData)\n external\n returns (bytes4);\n\n /**\n * @notice Hook called after taking an order\n * @param sender The sender of the take transaction\n * @param params The parameters of the take transaction\n * @param takenUnit The unit that was taken\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function afterTake(\n address sender,\n IBookManager.TakeParams calldata params,\n uint64 takenUnit,\n bytes calldata hookData\n ) external returns (bytes4);\n\n /**\n * @notice Hook called before canceling an order\n * @param sender The sender of the cancel transaction\n * @param params The parameters of the cancel transaction\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function beforeCancel(address sender, IBookManager.CancelParams calldata params, bytes calldata hookData)\n external\n returns (bytes4);\n\n /**\n * @notice Hook called after canceling an order\n * @param sender The sender of the cancel transaction\n * @param params The parameters of the cancel transaction\n * @param canceledUnit The unit that was canceled\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function afterCancel(\n address sender,\n IBookManager.CancelParams calldata params,\n uint64 canceledUnit,\n bytes calldata hookData\n ) external returns (bytes4);\n\n /**\n * @notice Hook called before claiming an order\n * @param sender The sender of the claim transaction\n * @param orderId The id of the order being claimed\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function beforeClaim(address sender, OrderId orderId, bytes calldata hookData) external returns (bytes4);\n\n /**\n * @notice Hook called after claiming an order\n * @param sender The sender of the claim transaction\n * @param orderId The id of the order being claimed\n * @param claimedUnit The unit that was claimed\n * @param hookData The data passed to the hook\n * @return Returns the function selector if the hook is successful\n */\n function afterClaim(address sender, OrderId orderId, uint64 claimedUnit, bytes calldata hookData)\n external\n returns (bytes4);\n}\n" + }, + "v2-core/interfaces/ILocker.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ILocker\n * @notice Interface for the locker contract\n */\ninterface ILocker {\n /**\n * @notice Called by the book manager on `msg.sender` when a lock is acquired\n * @param data The data that was passed to the call to lock\n * @return Any data that you want to be returned from the lock call\n */\n function lockAcquired(address lockCaller, bytes calldata data) external returns (bytes memory);\n}\n" + }, + "v2-core/libraries/BookId.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {IBookManager} from \"../interfaces/IBookManager.sol\";\n\ntype BookId is uint192;\n\nlibrary BookIdLibrary {\n function toId(IBookManager.BookKey memory bookKey) internal pure returns (BookId id) {\n bytes32 hash = keccak256(abi.encode(bookKey));\n assembly {\n id := and(hash, 0xffffffffffffffffffffffffffffffffffffffffffffffff)\n }\n }\n}\n" + }, + "v2-core/libraries/Currency.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ntype Currency is address;\n\n/// @title CurrencyLibrary\n/// @dev This library allows for transferring and holding native tokens and ERC20 tokens\nlibrary CurrencyLibrary {\n using CurrencyLibrary for Currency;\n\n /// @notice Thrown when a native transfer fails\n error NativeTransferFailed();\n\n /// @notice Thrown when an ERC20 transfer fails\n error ERC20TransferFailed();\n\n Currency public constant NATIVE = Currency.wrap(address(0));\n\n function transfer(Currency currency, address to, uint256 amount) internal {\n // implementation from\n // https://github.com/transmissions11/solmate/blob/e8f96f25d48fe702117ce76c79228ca4f20206cb/src/utils/SafeTransferLib.sol\n\n bool success;\n if (currency.isNative()) {\n assembly {\n // Transfer the ETH and store if it succeeded or not.\n success := call(gas(), to, amount, 0, 0, 0, 0)\n }\n\n if (!success) revert NativeTransferFailed();\n } else {\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata into memory, beginning with the function selector.\n mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\n mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"to\" argument.\n mstore(add(freeMemoryPointer, 36), amount) // Append the \"amount\" argument. Masking not required as it's a full 32 byte type.\n\n success :=\n and(\n // Set success to whether the call reverted, if not we check it either\n // returned exactly 1 (can't just be non-zero data), or had no return data.\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n // Counterintuitively, this call must be positioned second to the or() call in the\n // surrounding and() call or else returndatasize() will be zero during the computation.\n call(gas(), currency, 0, freeMemoryPointer, 68, 0, 32)\n )\n }\n\n if (!success) revert ERC20TransferFailed();\n }\n }\n\n function balanceOfSelf(Currency currency) internal view returns (uint256) {\n if (currency.isNative()) return address(this).balance;\n else return IERC20(Currency.unwrap(currency)).balanceOf(address(this));\n }\n\n function equals(Currency currency, Currency other) internal pure returns (bool) {\n return Currency.unwrap(currency) == Currency.unwrap(other);\n }\n\n function isNative(Currency currency) internal pure returns (bool) {\n return Currency.unwrap(currency) == Currency.unwrap(NATIVE);\n }\n\n function toId(Currency currency) internal pure returns (uint256) {\n return uint160(Currency.unwrap(currency));\n }\n\n function fromId(uint256 id) internal pure returns (Currency) {\n return Currency.wrap(address(uint160(id)));\n }\n}\n" + }, + "v2-core/libraries/FeePolicy.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {Math} from \"./Math.sol\";\n\ntype FeePolicy is uint24;\n\nlibrary FeePolicyLibrary {\n uint256 internal constant RATE_PRECISION = 10 ** 6;\n int256 internal constant MAX_FEE_RATE = 500000;\n int256 internal constant MIN_FEE_RATE = -500000;\n\n uint256 internal constant RATE_MASK = 0x7fffff; // 23 bits\n\n error InvalidFeePolicy();\n\n function encode(bool usesQuote_, int24 rate_) internal pure returns (FeePolicy feePolicy) {\n if (rate_ > MAX_FEE_RATE || rate_ < MIN_FEE_RATE) {\n revert InvalidFeePolicy();\n }\n\n uint256 mask = usesQuote_ ? 1 << 23 : 0;\n assembly {\n feePolicy := or(mask, add(and(rate_, 0xffffff), MAX_FEE_RATE))\n }\n }\n\n function isValid(FeePolicy self) internal pure returns (bool) {\n int24 r = rate(self);\n\n return !(r > MAX_FEE_RATE || r < MIN_FEE_RATE);\n }\n\n function usesQuote(FeePolicy self) internal pure returns (bool f) {\n assembly {\n f := shr(23, self)\n }\n }\n\n function rate(FeePolicy self) internal pure returns (int24 r) {\n assembly {\n r := sub(and(self, RATE_MASK), MAX_FEE_RATE)\n }\n }\n\n function calculateFee(FeePolicy self, uint256 amount, bool reverseRounding) internal pure returns (int256 fee) {\n int24 r = rate(self);\n\n bool positive = r > 0;\n uint256 absRate;\n unchecked {\n absRate = uint256(uint24(positive ? r : -r));\n }\n // @dev absFee must be less than type(int256).max\n uint256 absFee = Math.divide(amount * absRate, RATE_PRECISION, reverseRounding ? !positive : positive);\n fee = positive ? int256(absFee) : -int256(absFee);\n }\n\n function calculateOriginalAmount(FeePolicy self, uint256 amount, bool reverseFee)\n internal\n pure\n returns (uint256 originalAmount)\n {\n int24 r = rate(self);\n\n bool positive = r > 0;\n uint256 divider;\n assembly {\n if reverseFee { r := sub(0, r) }\n divider := add(RATE_PRECISION, r)\n }\n originalAmount = Math.divide(amount * RATE_PRECISION, divider, positive);\n }\n}\n" + }, + "v2-core/libraries/Lockers.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.23;\n\nimport {IHooks} from \"../interfaces/IHooks.sol\";\n\n/// @author Clober\n/// @author Modified from Uniswap V4 (https://github.com/Uniswap/v4-core/tree/98680ebc1a654120e995d53a5b10ec6fe153066f)\n/// @notice Contains data about pool lockers.\n\n/// @dev This library manages a custom storage implementation for a queue\n/// that tracks current lockers. The \"sentinel\" storage slot for this data structure,\n/// always passed in as IPoolManager.LockData storage self, stores not just the current\n/// length of the queue but also the global count of non-zero deltas across all lockers.\n/// The values of the data structure start at OFFSET, and each value is a locker address.\nlibrary Lockers {\n /// struct LockData {\n /// /// @notice The current number of active lockers\n /// uint128 length;\n /// /// @notice The total number of nonzero deltas over all active + completed lockers\n /// uint128 nonzeroDeltaCount;\n /// }\n // uint256(keccak256(\"LockData\")) + 1\n uint256 internal constant LOCK_DATA_SLOT = 0x760a9a962ae3d184e99c0483cf5684fb3170f47116ca4f445c50209da4f4f907;\n\n // uint256(keccak256(\"Lockers\")) + 1\n uint256 internal constant LOCKERS_SLOT = 0x722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b1;\n\n // The number of slots per item in the lockers array\n uint256 internal constant LOCKER_STRUCT_SIZE = 2;\n\n // uint256(keccak256(\"HookAddress\")) + 1\n uint256 internal constant HOOK_ADDRESS_SLOT = 0xfcac7593714b88fec0c578a53e9f3f6e4b47eb26c9dcaa7eff23a3ac156be422;\n\n uint256 internal constant NONZERO_DELTA_COUNT_OFFSET = 2 ** 128;\n\n uint256 internal constant LENGTH_MASK = (1 << 128) - 1;\n\n /// @dev Pushes a locker onto the end of the queue, and updates the sentinel storage slot.\n function push(address locker, address lockCaller) internal {\n assembly {\n let data := tload(LOCK_DATA_SLOT)\n let l := and(data, LENGTH_MASK)\n\n // LOCKERS_SLOT + l * LOCKER_STRUCT_SIZE\n let indexToWrite := add(LOCKERS_SLOT, mul(l, LOCKER_STRUCT_SIZE))\n\n // in the next storage slot, write the locker and lockCaller\n tstore(indexToWrite, locker)\n tstore(add(indexToWrite, 1), lockCaller)\n\n // increase the length\n tstore(LOCK_DATA_SLOT, add(data, 1))\n }\n }\n\n function lockData() internal view returns (uint128 l, uint128 nonzeroDeltaCount) {\n assembly {\n let data := tload(LOCK_DATA_SLOT)\n l := and(data, LENGTH_MASK)\n nonzeroDeltaCount := shr(128, data)\n }\n }\n\n function length() internal view returns (uint128 l) {\n assembly {\n l := and(tload(LOCK_DATA_SLOT), LENGTH_MASK)\n }\n }\n\n /// @dev Pops a locker off the end of the queue. Note that no storage gets cleared.\n function pop() internal {\n assembly {\n let data := tload(LOCK_DATA_SLOT)\n let l := and(data, LENGTH_MASK)\n if iszero(l) {\n mstore(0x00, 0xf1c77ed0) // LockersPopFailed()\n revert(0x1c, 0x04)\n }\n\n // LOCKERS_SLOT + (l - 1) * LOCKER_STRUCT_SIZE\n let indexToWrite := add(LOCKERS_SLOT, mul(sub(l, 1), LOCKER_STRUCT_SIZE))\n\n // in the next storage slot, delete the locker and lockCaller\n tstore(indexToWrite, 0)\n tstore(add(indexToWrite, 1), 0)\n\n // decrease the length\n tstore(LOCK_DATA_SLOT, sub(data, 1))\n }\n }\n\n function getLocker(uint256 i) internal view returns (address locker) {\n assembly {\n // LOCKERS_SLOT + (i * LOCKER_STRUCT_SIZE)\n locker := tload(add(LOCKERS_SLOT, mul(i, LOCKER_STRUCT_SIZE)))\n }\n }\n\n function getLockCaller(uint256 i) internal view returns (address locker) {\n assembly {\n // LOCKERS_SLOT + (i * LOCKER_STRUCT_SIZE + 1)\n locker := tload(add(LOCKERS_SLOT, add(mul(i, LOCKER_STRUCT_SIZE), 1)))\n }\n }\n\n function getCurrentLocker() internal view returns (address) {\n unchecked {\n uint256 l = length();\n return l > 0 ? getLocker(l - 1) : address(0);\n }\n }\n\n function getCurrentLockCaller() internal view returns (address) {\n unchecked {\n uint256 l = length();\n return l > 0 ? getLockCaller(l - 1) : address(0);\n }\n }\n\n function incrementNonzeroDeltaCount() internal {\n assembly {\n tstore(LOCK_DATA_SLOT, add(tload(LOCK_DATA_SLOT), NONZERO_DELTA_COUNT_OFFSET))\n }\n }\n\n function decrementNonzeroDeltaCount() internal {\n assembly {\n tstore(LOCK_DATA_SLOT, sub(tload(LOCK_DATA_SLOT), NONZERO_DELTA_COUNT_OFFSET))\n }\n }\n\n function getCurrentHook() internal view returns (IHooks currentHook) {\n return IHooks(getHook(length()));\n }\n\n function getHook(uint256 i) internal view returns (address hook) {\n assembly {\n hook := tload(add(HOOK_ADDRESS_SLOT, i))\n }\n }\n\n function setCurrentHook(IHooks currentHook) internal returns (bool set) {\n // Set the hook address for the current locker if the address is 0.\n // If the address is nonzero, a hook has already been set for this lock, and is not allowed to be updated or cleared at the end of the call.\n if (address(getCurrentHook()) == address(0)) {\n uint256 l = length();\n assembly {\n tstore(add(HOOK_ADDRESS_SLOT, l), currentHook)\n }\n return true;\n }\n }\n\n function clearCurrentHook() internal {\n uint256 l = length();\n assembly {\n tstore(add(HOOK_ADDRESS_SLOT, l), 0)\n }\n }\n}\n" + }, + "v2-core/libraries/Math.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.0;\n\nlibrary Math {\n function divide(uint256 a, uint256 b, bool roundingUp) internal pure returns (uint256 ret) {\n // In the OrderBook contract code, b is never zero.\n assembly {\n ret := add(div(a, b), and(gt(mod(a, b), 0), roundingUp))\n }\n }\n\n /// @dev Returns `ln(x)`, denominated in `WAD`.\n /// Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln\n function lnWad(int256 x) internal pure returns (int256 r) {\n /// @solidity memory-safe-assembly\n assembly {\n // We want to convert `x` from `10**18` fixed point to `2**96` fixed point.\n // We do this by multiplying by `2**96 / 10**18`. But since\n // `ln(x * C) = ln(x) + ln(C)`, we can simply do nothing here\n // and add `ln(2**96 / 10**18)` at the end.\n\n // Compute `k = log2(x) - 96`, `r = 159 - k = 255 - log2(x) = 255 ^ log2(x)`.\n r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n r := or(r, shl(4, lt(0xffff, shr(r, x))))\n r := or(r, shl(3, lt(0xff, shr(r, x))))\n // We place the check here for more optimal stack operations.\n if iszero(sgt(x, 0)) {\n mstore(0x00, 0x1615e638) // `LnWadUndefined()`.\n revert(0x1c, 0x04)\n }\n // forgefmt: disable-next-item\n r := xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),\n 0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff))\n\n // Reduce range of x to (1, 2) * 2**96\n // ln(2^k * x) = k * ln(2) + ln(x)\n x := shr(159, shl(r, x))\n\n // Evaluate using a (8, 8)-term rational approximation.\n // `p` is made monic, we will multiply by a scale factor later.\n // forgefmt: disable-next-item\n let p := sub( // This heavily nested expression is to avoid stack-too-deep for via-ir.\n sar(96, mul(add(43456485725739037958740375743393,\n sar(96, mul(add(24828157081833163892658089445524,\n sar(96, mul(add(3273285459638523848632254066296,\n x), x))), x))), x)), 11111509109440967052023855526967)\n p := sub(sar(96, mul(p, x)), 45023709667254063763336534515857)\n p := sub(sar(96, mul(p, x)), 14706773417378608786704636184526)\n p := sub(mul(p, x), shl(96, 795164235651350426258249787498))\n // We leave `p` in `2**192` basis so we don't need to scale it back up for the division.\n\n // `q` is monic by convention.\n let q := add(5573035233440673466300451813936, x)\n q := add(71694874799317883764090561454958, sar(96, mul(x, q)))\n q := add(283447036172924575727196451306956, sar(96, mul(x, q)))\n q := add(401686690394027663651624208769553, sar(96, mul(x, q)))\n q := add(204048457590392012362485061816622, sar(96, mul(x, q)))\n q := add(31853899698501571402653359427138, sar(96, mul(x, q)))\n q := add(909429971244387300277376558375, sar(96, mul(x, q)))\n\n // `p / q` is in the range `(0, 0.125) * 2**96`.\n\n // Finalization, we need to:\n // - Multiply by the scale factor `s = 5.549…`.\n // - Add `ln(2**96 / 10**18)`.\n // - Add `k * ln(2)`.\n // - Multiply by `10**18 / 2**96 = 5**18 >> 78`.\n\n // The q polynomial is known not to have zeros in the domain.\n // No scaling required because p is already `2**96` too large.\n p := sdiv(p, q)\n // Multiply by the scaling factor: `s * 5**18 * 2**96`, base is now `5**18 * 2**192`.\n p := mul(1677202110996718588342820967067443963516166, p)\n // Add `ln(2) * k * 5**18 * 2**192`.\n // forgefmt: disable-next-item\n p := add(mul(16597577552685614221487285958193947469193820559219878177908093499208371, sub(159, r)), p)\n // Base conversion: mul `2**96 / (5**18 * 2**192)`.\n r := sdiv(p, 302231454903657293676544000000000000000000)\n }\n }\n}\n" + }, + "v2-core/libraries/OrderId.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.0;\n\nimport {Tick} from \"./Tick.sol\";\nimport {BookId} from \"./BookId.sol\";\n\ntype OrderId is uint256;\n\nlibrary OrderIdLibrary {\n /**\n * @dev Encode the order id.\n * @param bookId The book id.\n * @param tick The tick.\n * @param index The index.\n * @return id The order id.\n */\n function encode(BookId bookId, Tick tick, uint40 index) internal pure returns (OrderId id) {\n // @dev If we just use tick at the assembly code, the code will convert tick into bytes32.\n // e.g. When index == -2, the shifted value( shl(40, tick) ) will be\n // 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000 instead of 0xfffffffe0000000000\n // Therefore, we have to safely cast tick into uint256 first.\n uint256 _tick = uint256(uint24(Tick.unwrap(tick)));\n assembly {\n id := add(index, add(shl(40, _tick), shl(64, bookId)))\n }\n }\n\n function decode(OrderId id) internal pure returns (BookId bookId, Tick tick, uint40 index) {\n assembly {\n bookId := shr(64, id)\n tick := and(shr(40, id), 0xffffff)\n index := and(id, 0xffffffffff)\n }\n }\n\n function getBookId(OrderId id) internal pure returns (BookId bookId) {\n assembly {\n bookId := shr(64, id)\n }\n }\n\n function getTick(OrderId id) internal pure returns (Tick tick) {\n assembly {\n tick := and(shr(40, id), 0xffffff)\n }\n }\n\n function getIndex(OrderId id) internal pure returns (uint40 index) {\n assembly {\n index := and(id, 0xffffffffff)\n }\n }\n}\n" + }, + "v2-core/libraries/SignificantBit.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.0;\n\nlibrary SignificantBit {\n // http://supertech.csail.mit.edu/papers/debruijn.pdf\n uint256 internal constant DEBRUIJN_SEQ = 0x818283848586878898A8B8C8D8E8F929395969799A9B9D9E9FAAEB6BEDEEFF;\n bytes internal constant DEBRUIJN_INDEX =\n hex\"0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8\";\n\n /**\n * @notice Finds the index of the least significant bit.\n * @param x The value to compute the least significant bit for. Must be a non-zero value.\n * @return ret The index of the least significant bit.\n */\n function leastSignificantBit(uint256 x) internal pure returns (uint8) {\n require(x > 0);\n uint256 index;\n assembly {\n index := shr(248, mul(and(x, add(not(x), 1)), DEBRUIJN_SEQ))\n }\n return uint8(DEBRUIJN_INDEX[index]); // can optimize with CODECOPY opcode\n }\n\n function mostSignificantBit(uint256 x) internal pure returns (uint8 msb) {\n require(x > 0);\n assembly {\n let f := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n x := shr(f, x)\n f := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\n msb := or(msb, f)\n x := shr(f, x)\n f := shl(5, gt(x, 0xFFFFFFFF))\n msb := or(msb, f)\n x := shr(f, x)\n f := shl(4, gt(x, 0xFFFF))\n msb := or(msb, f)\n x := shr(f, x)\n f := shl(3, gt(x, 0xFF))\n msb := or(msb, f)\n x := shr(f, x)\n f := shl(2, gt(x, 0xF))\n msb := or(msb, f)\n x := shr(f, x)\n f := shl(1, gt(x, 0x3))\n msb := or(msb, f)\n x := shr(f, x)\n f := gt(x, 0x1)\n msb := or(msb, f)\n }\n }\n}\n" + }, + "v2-core/libraries/Tick.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\npragma solidity ^0.8.20;\n\nimport {Math} from \"./Math.sol\";\n\ntype Tick is int24;\n\nlibrary TickLibrary {\n using Math for *;\n using TickLibrary for Tick;\n\n error InvalidTick();\n error InvalidPrice();\n error TickOverflow();\n\n int24 internal constant MAX_TICK = 2 ** 19 - 1;\n int24 internal constant MIN_TICK = -MAX_TICK;\n\n uint256 internal constant MIN_PRICE = 1350587;\n uint256 internal constant MAX_PRICE = 4647684107270898330752324302845848816923571339324334;\n\n uint256 private constant _R0 = 0xfff97272373d413259a46990;\n uint256 private constant _R1 = 0xfff2e50f5f656932ef12357c;\n uint256 private constant _R2 = 0xffe5caca7e10e4e61c3624ea;\n uint256 private constant _R3 = 0xffcb9843d60f6159c9db5883;\n uint256 private constant _R4 = 0xff973b41fa98c081472e6896;\n uint256 private constant _R5 = 0xff2ea16466c96a3843ec78b3;\n uint256 private constant _R6 = 0xfe5dee046a99a2a811c461f1;\n uint256 private constant _R7 = 0xfcbe86c7900a88aedcffc83b;\n uint256 private constant _R8 = 0xf987a7253ac413176f2b074c;\n uint256 private constant _R9 = 0xf3392b0822b70005940c7a39;\n uint256 private constant _R10 = 0xe7159475a2c29b7443b29c7f;\n uint256 private constant _R11 = 0xd097f3bdfd2022b8845ad8f7;\n uint256 private constant _R12 = 0xa9f746462d870fdf8a65dc1f;\n uint256 private constant _R13 = 0x70d869a156d2a1b890bb3df6;\n uint256 private constant _R14 = 0x31be135f97d08fd981231505;\n uint256 private constant _R15 = 0x9aa508b5b7a84e1c677de54;\n uint256 private constant _R16 = 0x5d6af8dedb81196699c329;\n uint256 private constant _R17 = 0x2216e584f5fa1ea92604;\n uint256 private constant _R18 = 0x48a170391f7dc42;\n uint256 private constant _R19 = 0x149b34;\n\n function validateTick(Tick tick) internal pure {\n if (Tick.unwrap(tick) > MAX_TICK || Tick.unwrap(tick) < MIN_TICK) revert InvalidTick();\n }\n\n modifier validatePrice(uint256 price) {\n if (price > MAX_PRICE || price < MIN_PRICE) revert InvalidPrice();\n _;\n }\n\n function fromPrice(uint256 price) internal pure validatePrice(price) returns (Tick) {\n unchecked {\n int24 tick = int24((int256(price).lnWad() * 42951820407860) / 2 ** 128);\n if (toPrice(Tick.wrap(tick)) > price) return Tick.wrap(tick - 1);\n return Tick.wrap(tick);\n }\n }\n\n function toPrice(Tick tick) internal pure returns (uint256 price) {\n validateTick(tick);\n int24 tickValue = Tick.unwrap(tick);\n uint256 absTick = uint24(tickValue < 0 ? -tickValue : tickValue);\n\n unchecked {\n if (absTick & 0x1 != 0) price = _R0;\n else price = 1 << 96;\n if (absTick & 0x2 != 0) price = (price * _R1) >> 96;\n if (absTick & 0x4 != 0) price = (price * _R2) >> 96;\n if (absTick & 0x8 != 0) price = (price * _R3) >> 96;\n if (absTick & 0x10 != 0) price = (price * _R4) >> 96;\n if (absTick & 0x20 != 0) price = (price * _R5) >> 96;\n if (absTick & 0x40 != 0) price = (price * _R6) >> 96;\n if (absTick & 0x80 != 0) price = (price * _R7) >> 96;\n if (absTick & 0x100 != 0) price = (price * _R8) >> 96;\n if (absTick & 0x200 != 0) price = (price * _R9) >> 96;\n if (absTick & 0x400 != 0) price = (price * _R10) >> 96;\n if (absTick & 0x800 != 0) price = (price * _R11) >> 96;\n if (absTick & 0x1000 != 0) price = (price * _R12) >> 96;\n if (absTick & 0x2000 != 0) price = (price * _R13) >> 96;\n if (absTick & 0x4000 != 0) price = (price * _R14) >> 96;\n if (absTick & 0x8000 != 0) price = (price * _R15) >> 96;\n if (absTick & 0x10000 != 0) price = (price * _R16) >> 96;\n if (absTick & 0x20000 != 0) price = (price * _R17) >> 96;\n if (absTick & 0x40000 != 0) price = (price * _R18) >> 96;\n }\n if (tickValue > 0) price = 0x1000000000000000000000000000000000000000000000000 / price;\n }\n\n function gt(Tick a, Tick b) internal pure returns (bool) {\n return Tick.unwrap(a) > Tick.unwrap(b);\n }\n\n function baseToQuote(Tick tick, uint256 base, bool roundingUp) internal pure returns (uint256) {\n return Math.divide((base * tick.toPrice()), 1 << 96, roundingUp);\n }\n\n function quoteToBase(Tick tick, uint256 quote, bool roundingUp) internal pure returns (uint256) {\n // @dev quote = unit(uint64) * unitSize(uint64) < 2^96\n // We don't need to check overflow here\n return Math.divide(quote << 96, tick.toPrice(), roundingUp);\n }\n}\n" + } + }, + "settings": { + "evmVersion": "cancun", + "optimizer": { + "enabled": true, + "runs": 1000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file