From cf66a8ef62340044f50ac6145c085b4e7687830a Mon Sep 17 00:00:00 2001 From: Gleb Alekseev Date: Mon, 1 Jul 2024 03:13:04 +0300 Subject: [PATCH] New drop for Adoption --- deployments/base/MerkleDrop128-44.json | 424 +++++++++++++++++++++++++ src/.latest | 2 +- 2 files changed, 425 insertions(+), 1 deletion(-) create mode 100644 deployments/base/MerkleDrop128-44.json diff --git a/deployments/base/MerkleDrop128-44.json b/deployments/base/MerkleDrop128-44.json new file mode 100644 index 00000000..ca7e6d37 --- /dev/null +++ b/deployments/base/MerkleDrop128-44.json @@ -0,0 +1,424 @@ +{ + "address": "0xFeE0AEeCEfdB5D4712b997A5Ec9d336E5455e3E2", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "bytes16", + "name": "merkleRoot_", + "type": "bytes16" + }, + { + "internalType": "uint256", + "name": "depth_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "DropAlreadyClaimed", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidProof", + "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": "SafeTransferFailed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "merkleProof", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depth", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "isClaimed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "merkleRoot", + "outputs": [ + { + "internalType": "bytes16", + "name": "", + "type": "bytes16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "rescueFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes16", + "name": "root", + "type": "bytes16" + }, + { + "internalType": "bytes16", + "name": "leaf", + "type": "bytes16" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "valid", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes16", + "name": "leaf", + "type": "bytes16" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "valid", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x1ed215f5ae856445a1b8fbbb9a08338c3ab77e3ba26eaa8d1d336e4c79ea691a", + "receipt": { + "to": null, + "from": "0x0BD61d605C64A857C3D94779aEf7cA295702b3A2", + "contractAddress": "0xFeE0AEeCEfdB5D4712b997A5Ec9d336E5455e3E2", + "transactionIndex": 43, + "gasUsed": "805628", + "logsBloom": "0x00000000000001000000000000000000000000000000000000800000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000010000000400000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000800000000000", + "blockHash": "0x92f364d3b5fc8c8e84636c161fde7c11343f6db714dc44c194b07c450a999f1d", + "transactionHash": "0x1ed215f5ae856445a1b8fbbb9a08338c3ab77e3ba26eaa8d1d336e4c79ea691a", + "logs": [ + { + "transactionIndex": 43, + "blockNumber": 15782909, + "transactionHash": "0x1ed215f5ae856445a1b8fbbb9a08338c3ab77e3ba26eaa8d1d336e4c79ea691a", + "address": "0xFeE0AEeCEfdB5D4712b997A5Ec9d336E5455e3E2", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000bd61d605c64a857c3d94779aef7ca295702b3a2" + ], + "data": "0x", + "logIndex": 110, + "blockHash": "0x92f364d3b5fc8c8e84636c161fde7c11343f6db714dc44c194b07c450a999f1d" + } + ], + "blockNumber": 15782909, + "cumulativeGasUsed": "6931862", + "status": 1, + "byzantium": true + }, + "args": [ + "0xc5fecC3a29Fb57B5024eEc8a2239d4621e111CBE", + "0xeb42483aeaa33fee2969dfd57ccb49c6", + "8" + ], + "numDeployments": 1, + "solcInputHash": "58c7166f1db63fd9944cc1372b0b579b", + "metadata": "{\"compiler\":{\"version\":\"0.8.23+commit.f704f362\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token_\",\"type\":\"address\"},{\"internalType\":\"bytes16\",\"name\":\"merkleRoot_\",\"type\":\"bytes16\"},{\"internalType\":\"uint256\",\"name\":\"depth_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DropAlreadyClaimed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"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\":\"SafeTransferFailed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"merkleProof\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depth\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"isClaimed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"merkleRoot\",\"outputs\":[{\"internalType\":\"bytes16\",\"name\":\"\",\"type\":\"bytes16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"rescueFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"},{\"internalType\":\"bytes16\",\"name\":\"root\",\"type\":\"bytes16\"},{\"internalType\":\"bytes16\",\"name\":\"leaf\",\"type\":\"bytes16\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"valid\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"},{\"internalType\":\"bytes16\",\"name\":\"leaf\",\"type\":\"bytes16\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"valid\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"AddressInsufficientBalance(address)\":[{\"details\":\"The ETH balance of the account is not enough to perform the operation.\"}],\"FailedInnerCall()\":[{\"details\":\"A call to an address target failed. The target may have reverted.\"}],\"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.\"}]},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current 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\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SignatureMerkleDrop128.sol\":\"SignatureMerkleDrop128\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@1inch/solidity-utils/contracts/interfaces/IDaiLikePermit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title IDaiLikePermit\\n * @dev Interface for Dai-like permit function allowing token spending via signatures.\\n */\\ninterface IDaiLikePermit {\\n /**\\n * @notice Approves spending of tokens via off-chain signatures.\\n * @param holder Token holder's address.\\n * @param spender Spender's address.\\n * @param nonce Current nonce of the holder.\\n * @param expiry Time when the permit expires.\\n * @param allowed True to allow, false to disallow spending.\\n * @param v, r, s Signature components.\\n */\\n function permit(\\n address holder,\\n address spender,\\n uint256 nonce,\\n uint256 expiry,\\n bool allowed,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n}\\n\",\"keccak256\":\"0xf8636c1c4631641c7b40ac65cd69e6ae04a99cf3358426c642dec02c6c774c82\",\"license\":\"MIT\"},\"@1inch/solidity-utils/contracts/interfaces/IERC7597Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title IERC7597Permit\\n * @dev A new extension for ERC-2612 permit, which has already been added to USDC v2.2.\\n */\\ninterface IERC7597Permit {\\n /**\\n * @notice Update allowance with a signed permit.\\n * @dev Signature bytes can be used for both EOA wallets and contract wallets.\\n * @param owner Token owner's address (Authorizer).\\n * @param spender Spender's address.\\n * @param value Amount of allowance.\\n * @param deadline The time at which the signature expires (unixtime).\\n * @param signature Unstructured bytes signature signed by an EOA wallet or a contract wallet.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n bytes memory signature\\n ) external;\\n}\\n\",\"keccak256\":\"0xaf148ecd4db0f44989a7417f6945bcfd18273c5096bc2b364e314e42c85c78cd\",\"license\":\"MIT\"},\"@1inch/solidity-utils/contracts/interfaces/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title IPermit2\\n * @dev Interface for a flexible permit system that extends ERC20 tokens to support permits in tokens lacking native permit functionality.\\n */\\ninterface IPermit2 {\\n /**\\n * @dev Struct for holding permit details.\\n * @param token ERC20 token address for which the permit is issued.\\n * @param amount The maximum amount allowed to spend.\\n * @param expiration Timestamp until which the permit is valid.\\n * @param nonce An incrementing value for each signature, unique per owner, token, and spender.\\n */\\n struct PermitDetails {\\n address token;\\n uint160 amount;\\n uint48 expiration;\\n uint48 nonce;\\n }\\n\\n /**\\n * @dev Struct for a single token allowance permit.\\n * @param details Permit details including token, amount, expiration, and nonce.\\n * @param spender Address authorized to spend the tokens.\\n * @param sigDeadline Deadline for the permit signature, ensuring timeliness of the permit.\\n */\\n struct PermitSingle {\\n PermitDetails details;\\n address spender;\\n uint256 sigDeadline;\\n }\\n\\n /**\\n * @dev Struct for packed allowance data to optimize storage.\\n * @param amount Amount allowed.\\n * @param expiration Permission expiry timestamp.\\n * @param nonce Unique incrementing value for tracking allowances.\\n */\\n struct PackedAllowance {\\n uint160 amount;\\n uint48 expiration;\\n uint48 nonce;\\n }\\n\\n /**\\n * @notice Executes a token transfer from one address to another.\\n * @param user The token owner's address.\\n * @param spender The address authorized to spend the tokens.\\n * @param amount The amount of tokens to transfer.\\n * @param token The address of the token being transferred.\\n */\\n function transferFrom(address user, address spender, uint160 amount, address token) external;\\n\\n /**\\n * @notice Issues a permit for spending tokens via a signed authorization.\\n * @param owner The token owner's address.\\n * @param permitSingle Struct containing the permit details.\\n * @param signature The signature proving the owner authorized the permit.\\n */\\n function permit(address owner, PermitSingle memory permitSingle, bytes calldata signature) external;\\n\\n /**\\n * @notice Retrieves the allowance details between a token owner and spender.\\n * @param user The token owner's address.\\n * @param token The token address.\\n * @param spender The spender's address.\\n * @return The packed allowance details.\\n */\\n function allowance(address user, address token, address spender) external view returns (PackedAllowance memory);\\n}\\n\",\"keccak256\":\"0x0e8375c63b72926e9073c5712fd6a181dce58ee155d73c57e34febace7949bfa\",\"license\":\"MIT\"},\"@1inch/solidity-utils/contracts/interfaces/IWETH.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/**\\n * @title IWETH\\n * @dev Interface for wrapper as WETH-like token.\\n */\\ninterface IWETH is IERC20 {\\n /**\\n * @notice Emitted when Ether is deposited to get wrapper tokens.\\n */\\n event Deposit(address indexed dst, uint256 wad);\\n\\n /**\\n * @notice Emitted when wrapper tokens is withdrawn as Ether.\\n */\\n event Withdrawal(address indexed src, uint256 wad);\\n\\n /**\\n * @notice Deposit Ether to get wrapper tokens.\\n */\\n function deposit() external payable;\\n\\n /**\\n * @notice Withdraw wrapped tokens as Ether.\\n * @param amount Amount of wrapped tokens to withdraw.\\n */\\n function withdraw(uint256 amount) external;\\n}\\n\",\"keccak256\":\"0x32989b79850e8a1ac6aab74878de2883f9537656ca06910dc0ae76833cc446e2\",\"license\":\"MIT\"},\"@1inch/solidity-utils/contracts/libraries/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @title ECDSA signature operations\\n * @notice Provides functions for recovering addresses from signatures and verifying signatures, including support for EIP-2098 compact signatures.\\n */\\nlibrary ECDSA {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n uint256 private constant _S_BOUNDARY = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 + 1;\\n uint256 private constant _COMPACT_S_MASK = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n uint256 private constant _COMPACT_V_SHIFT = 255;\\n\\n /**\\n * @notice Recovers the signer's address from the signature.\\n * @dev Recovers the address that has signed a hash with `(v, r, s)` signature.\\n * @param hash The keccak256 hash of the data signed.\\n * @param v The recovery byte of the signature.\\n * @param r The first 32 bytes of the signature.\\n * @param s The second 32 bytes of the signature.\\n * @return signer The address of the signer.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal view returns (address signer) {\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n if lt(s, _S_BOUNDARY) {\\n let ptr := mload(0x40)\\n\\n mstore(ptr, hash)\\n mstore(add(ptr, 0x20), v)\\n mstore(add(ptr, 0x40), r)\\n mstore(add(ptr, 0x60), s)\\n mstore(0, 0)\\n pop(staticcall(gas(), 0x1, ptr, 0x80, 0, 0x20))\\n signer := mload(0)\\n }\\n }\\n }\\n\\n /**\\n * @notice Recovers the signer's address from the signature using `r` and `vs` components.\\n * @dev Recovers the address that has signed a hash with `r` and `vs`, where `vs` combines `v` and `s`.\\n * @param hash The keccak256 hash of the data signed.\\n * @param r The first 32 bytes of the signature.\\n * @param vs The combined `v` and `s` values of the signature.\\n * @return signer The address of the signer.\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal view returns (address signer) {\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n let s := and(vs, _COMPACT_S_MASK)\\n if lt(s, _S_BOUNDARY) {\\n let ptr := mload(0x40)\\n\\n mstore(ptr, hash)\\n mstore(add(ptr, 0x20), add(27, shr(_COMPACT_V_SHIFT, vs)))\\n mstore(add(ptr, 0x40), r)\\n mstore(add(ptr, 0x60), s)\\n mstore(0, 0)\\n pop(staticcall(gas(), 0x1, ptr, 0x80, 0, 0x20))\\n signer := mload(0)\\n }\\n }\\n }\\n\\n /**\\n * @notice Recovers the signer's address from a hash and a signature.\\n * @param hash The keccak256 hash of the signed data.\\n * @param signature The full signature from which the signer will be recovered.\\n * @return signer The address of the signer.\\n */\\n /// @dev WARNING!!!\\n /// There is a known signature malleability issue with two representations of signatures!\\n /// Even though this function is able to verify both standard 65-byte and compact 64-byte EIP-2098 signatures\\n /// one should never use raw signatures for any kind of invalidation logic in their code.\\n /// As the standard and compact representations are interchangeable any invalidation logic that relies on\\n /// signature uniqueness will get rekt.\\n /// More info: https://github.com/OpenZeppelin/openzeppelin-contracts/security/advisories/GHSA-4h98-2769-gh6h\\n function recover(bytes32 hash, bytes calldata signature) internal view returns (address signer) {\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n let ptr := mload(0x40)\\n\\n // memory[ptr:ptr+0x80] = (hash, v, r, s)\\n switch signature.length\\n case 65 {\\n // memory[ptr+0x20:ptr+0x80] = (v, r, s)\\n mstore(add(ptr, 0x20), byte(0, calldataload(add(signature.offset, 0x40))))\\n calldatacopy(add(ptr, 0x40), signature.offset, 0x40)\\n }\\n case 64 {\\n // memory[ptr+0x20:ptr+0x80] = (v, r, s)\\n let vs := calldataload(add(signature.offset, 0x20))\\n mstore(add(ptr, 0x20), add(27, shr(_COMPACT_V_SHIFT, vs)))\\n calldatacopy(add(ptr, 0x40), signature.offset, 0x20)\\n mstore(add(ptr, 0x60), and(vs, _COMPACT_S_MASK))\\n }\\n default {\\n ptr := 0\\n }\\n\\n if ptr {\\n if lt(mload(add(ptr, 0x60)), _S_BOUNDARY) {\\n // memory[ptr:ptr+0x20] = (hash)\\n mstore(ptr, hash)\\n\\n mstore(0, 0)\\n pop(staticcall(gas(), 0x1, ptr, 0x80, 0, 0x20))\\n signer := mload(0)\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Verifies the signature for a hash, either by recovering the signer or using EIP-1271's `isValidSignature` function.\\n * @dev Attempts to recover the signer's address from the signature; if the address is non-zero, checks if it's valid according to EIP-1271.\\n * @param signer The address to validate the signature against.\\n * @param hash The hash of the signed data.\\n * @param signature The signature to verify.\\n * @return success True if the signature is verified, false otherwise.\\n */\\n function recoverOrIsValidSignature(\\n address signer,\\n bytes32 hash,\\n bytes calldata signature\\n ) internal view returns (bool success) {\\n if (signer == address(0)) return false;\\n if ((signature.length == 64 || signature.length == 65) && recover(hash, signature) == signer) {\\n return true;\\n }\\n return isValidSignature(signer, hash, signature);\\n }\\n\\n /**\\n * @notice Verifies the signature for a hash, either by recovering the signer or using EIP-1271's `isValidSignature` function.\\n * @dev Attempts to recover the signer's address from the signature; if the address is non-zero, checks if it's valid according to EIP-1271.\\n * @param signer The address to validate the signature against.\\n * @param hash The hash of the signed data.\\n * @param v The recovery byte of the signature.\\n * @param r The first 32 bytes of the signature.\\n * @param s The second 32 bytes of the signature.\\n * @return success True if the signature is verified, false otherwise.\\n */\\n function recoverOrIsValidSignature(\\n address signer,\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal view returns (bool success) {\\n if (signer == address(0)) return false;\\n if (recover(hash, v, r, s) == signer) {\\n return true;\\n }\\n return isValidSignature(signer, hash, v, r, s);\\n }\\n\\n /**\\n * @notice Verifies the signature for a hash, either by recovering the signer or using EIP-1271's `isValidSignature` function.\\n * @dev Attempts to recover the signer's address from the signature; if the address is non-zero, checks if it's valid according to EIP-1271.\\n * @param signer The address to validate the signature against.\\n * @param hash The hash of the signed data.\\n * @param r The first 32 bytes of the signature.\\n * @param vs The combined `v` and `s` values of the signature.\\n * @return success True if the signature is verified, false otherwise.\\n */\\n function recoverOrIsValidSignature(\\n address signer,\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal view returns (bool success) {\\n if (signer == address(0)) return false;\\n if (recover(hash, r, vs) == signer) {\\n return true;\\n }\\n return isValidSignature(signer, hash, r, vs);\\n }\\n\\n /**\\n * @notice Verifies the signature for a given hash, attempting to recover the signer's address or validates it using EIP-1271 for 65-byte signatures.\\n * @dev Attempts to recover the signer's address from the signature. If the address is a contract, checks if the signature is valid according to EIP-1271.\\n * @param signer The expected signer's address.\\n * @param hash The keccak256 hash of the signed data.\\n * @param r The first 32 bytes of the signature.\\n * @param vs The last 32 bytes of the signature, with the last byte being the recovery id.\\n * @return success True if the signature is valid, false otherwise.\\n */\\n function recoverOrIsValidSignature65(\\n address signer,\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal view returns (bool success) {\\n if (signer == address(0)) return false;\\n if (recover(hash, r, vs) == signer) {\\n return true;\\n }\\n return isValidSignature65(signer, hash, r, vs);\\n }\\n\\n /**\\n * @notice Validates a signature for a hash using EIP-1271, if `signer` is a contract.\\n * @dev Makes a static call to `signer` with `isValidSignature` function selector from EIP-1271.\\n * @param signer The address of the signer to validate against, which could be an EOA or a contract.\\n * @param hash The hash of the signed data.\\n * @param signature The signature to validate.\\n * @return success True if the signature is valid according to EIP-1271, false otherwise.\\n */\\n function isValidSignature(\\n address signer,\\n bytes32 hash,\\n bytes calldata signature\\n ) internal view returns (bool success) {\\n // (bool success, bytes memory data) = signer.staticcall(abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature));\\n // return success && data.length >= 4 && abi.decode(data, (bytes4)) == IERC1271.isValidSignature.selector;\\n bytes4 selector = IERC1271.isValidSignature.selector;\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n let ptr := mload(0x40)\\n\\n mstore(ptr, selector)\\n mstore(add(ptr, 0x04), hash)\\n mstore(add(ptr, 0x24), 0x40)\\n mstore(add(ptr, 0x44), signature.length)\\n calldatacopy(add(ptr, 0x64), signature.offset, signature.length)\\n if staticcall(gas(), signer, ptr, add(0x64, signature.length), 0, 0x20) {\\n success := and(eq(selector, mload(0)), eq(returndatasize(), 0x20))\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates a signature for a hash using EIP-1271, if `signer` is a contract.\\n * @dev Makes a static call to `signer` with `isValidSignature` function selector from EIP-1271.\\n * @param signer The address of the signer to validate against, which could be an EOA or a contract.\\n * @param hash The hash of the signed data.\\n * @param v The recovery byte of the signature.\\n * @param r The first 32 bytes of the signature.\\n * @param s The second 32 bytes of the signature.\\n * @return success True if the signature is valid according to EIP-1271, false otherwise.\\n */\\n function isValidSignature(\\n address signer,\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal view returns (bool success) {\\n bytes4 selector = IERC1271.isValidSignature.selector;\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n let ptr := mload(0x40)\\n\\n mstore(ptr, selector)\\n mstore(add(ptr, 0x04), hash)\\n mstore(add(ptr, 0x24), 0x40)\\n mstore(add(ptr, 0x44), 65)\\n mstore(add(ptr, 0x64), r)\\n mstore(add(ptr, 0x84), s)\\n mstore8(add(ptr, 0xa4), v)\\n if staticcall(gas(), signer, ptr, 0xa5, 0, 0x20) {\\n success := and(eq(selector, mload(0)), eq(returndatasize(), 0x20))\\n }\\n }\\n }\\n\\n /**\\n * @notice Validates a signature for a hash using EIP-1271, if `signer` is a contract.\\n * @dev Makes a static call to `signer` with `isValidSignature` function selector from EIP-1271.\\n * @param signer The address of the signer to validate against, which could be an EOA or a contract.\\n * @param hash The hash of the signed data.\\n * @param r The first 32 bytes of the signature.\\n * @param vs The last 32 bytes of the signature, with the last byte being the recovery id.\\n * @return success True if the signature is valid according to EIP-1271, false otherwise.\\n */\\n function isValidSignature(\\n address signer,\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal view returns (bool success) {\\n // (bool success, bytes memory data) = signer.staticcall(abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, abi.encodePacked(r, vs)));\\n // return success && data.length >= 4 && abi.decode(data, (bytes4)) == IERC1271.isValidSignature.selector;\\n bytes4 selector = IERC1271.isValidSignature.selector;\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n let ptr := mload(0x40)\\n\\n mstore(ptr, selector)\\n mstore(add(ptr, 0x04), hash)\\n mstore(add(ptr, 0x24), 0x40)\\n mstore(add(ptr, 0x44), 64)\\n mstore(add(ptr, 0x64), r)\\n mstore(add(ptr, 0x84), vs)\\n if staticcall(gas(), signer, ptr, 0xa4, 0, 0x20) {\\n success := and(eq(selector, mload(0)), eq(returndatasize(), 0x20))\\n }\\n }\\n }\\n\\n /**\\n * @notice Verifies if a 65-byte signature is valid for a given hash, according to EIP-1271.\\n * @param signer The address of the signer to validate against, which could be an EOA or a contract.\\n * @param hash The hash of the signed data.\\n * @param r The first 32 bytes of the signature.\\n * @param vs The combined `v` (recovery id) and `s` component of the signature, packed into the last 32 bytes.\\n * @return success True if the signature is valid according to EIP-1271, false otherwise.\\n */\\n function isValidSignature65(\\n address signer,\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal view returns (bool success) {\\n // (bool success, bytes memory data) = signer.staticcall(abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, abi.encodePacked(r, vs & ~uint256(1 << 255), uint8(vs >> 255))));\\n // return success && data.length >= 4 && abi.decode(data, (bytes4)) == IERC1271.isValidSignature.selector;\\n bytes4 selector = IERC1271.isValidSignature.selector;\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n let ptr := mload(0x40)\\n\\n mstore(ptr, selector)\\n mstore(add(ptr, 0x04), hash)\\n mstore(add(ptr, 0x24), 0x40)\\n mstore(add(ptr, 0x44), 65)\\n mstore(add(ptr, 0x64), r)\\n mstore(add(ptr, 0x84), and(vs, _COMPACT_S_MASK))\\n mstore8(add(ptr, 0xa4), add(27, shr(_COMPACT_V_SHIFT, vs)))\\n if staticcall(gas(), signer, ptr, 0xa5, 0, 0x20) {\\n success := and(eq(selector, mload(0)), eq(returndatasize(), 0x20))\\n }\\n }\\n }\\n\\n /**\\n * @notice Generates a hash compatible with Ethereum's signed message format.\\n * @dev Prepends the hash with Ethereum's message prefix before hashing it.\\n * @param hash The hash of the data to sign.\\n * @return res The Ethereum signed message hash.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 res) {\\n // 32 is the length in bytes of hash, enforced by the type signature above\\n // return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n mstore(0, 0x19457468657265756d205369676e6564204d6573736167653a0a333200000000) // \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\"\\n mstore(28, hash)\\n res := keccak256(0, 60)\\n }\\n }\\n\\n /**\\n * @notice Generates an EIP-712 compliant hash.\\n * @dev Encodes the domain separator and the struct hash according to EIP-712.\\n * @param domainSeparator The EIP-712 domain separator.\\n * @param structHash The EIP-712 struct hash.\\n * @return res The EIP-712 compliant hash.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 res) {\\n // return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n let ptr := mload(0x40)\\n mstore(ptr, 0x1901000000000000000000000000000000000000000000000000000000000000) // \\\"\\\\x19\\\\x01\\\"\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n res := keccak256(ptr, 66)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6e6265af95c2b68cd64a7b59049005ed994fc1706682636cf8bb22246b033b0\",\"license\":\"MIT\"},\"@1inch/solidity-utils/contracts/libraries/RevertReasonForwarder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title RevertReasonForwarder\\n * @notice Provides utilities for forwarding and retrieving revert reasons from failed external calls.\\n */\\nlibrary RevertReasonForwarder {\\n /**\\n * @dev Forwards the revert reason from the latest external call.\\n * This method allows propagating the revert reason of a failed external call to the caller.\\n */\\n function reRevert() internal pure {\\n // bubble up revert reason from latest external call\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n let ptr := mload(0x40)\\n returndatacopy(ptr, 0, returndatasize())\\n revert(ptr, returndatasize())\\n }\\n }\\n\\n /**\\n * @dev Retrieves the revert reason from the latest external call.\\n * This method enables capturing the revert reason of a failed external call for inspection or processing.\\n * @return reason The latest external call revert reason.\\n */\\n function reReason() internal pure returns (bytes memory reason) {\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n reason := mload(0x40)\\n let length := returndatasize()\\n mstore(reason, length)\\n returndatacopy(add(reason, 0x20), 0, length)\\n mstore(0x40, add(reason, add(0x20, length)))\\n }\\n }\\n}\\n\",\"keccak256\":\"0x97d8c950981f4da44ae1b01d9e597c4f99377797ec7ff7b1ef9648e4ecc1baa4\",\"license\":\"MIT\"},\"@1inch/solidity-utils/contracts/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\\\";\\nimport \\\"../interfaces/IDaiLikePermit.sol\\\";\\nimport \\\"../interfaces/IPermit2.sol\\\";\\nimport \\\"../interfaces/IERC7597Permit.sol\\\";\\nimport \\\"../interfaces/IWETH.sol\\\";\\nimport \\\"../libraries/RevertReasonForwarder.sol\\\";\\n\\n/**\\n * @title Implements efficient safe methods for ERC20 interface.\\n * @notice Compared to the standard ERC20, this implementation offers several enhancements:\\n * 1. more gas-efficient, providing significant savings in transaction costs.\\n * 2. support for different permit implementations\\n * 3. forceApprove functionality\\n * 4. support for WETH deposit and withdraw\\n */\\nlibrary SafeERC20 {\\n error SafeTransferFailed();\\n error SafeTransferFromFailed();\\n error ForceApproveFailed();\\n error SafeIncreaseAllowanceFailed();\\n error SafeDecreaseAllowanceFailed();\\n error SafePermitBadLength();\\n error Permit2TransferAmountTooHigh();\\n\\n // Uniswap Permit2 address\\n address private constant _PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;\\n bytes4 private constant _PERMIT_LENGTH_ERROR = 0x68275857; // SafePermitBadLength.selector\\n uint256 private constant _RAW_CALL_GAS_LIMIT = 5000;\\n\\n /**\\n * @notice Fetches the balance of a specific ERC20 token held by an account.\\n * Consumes less gas then regular `ERC20.balanceOf`.\\n * @dev Note that the implementation does not perform dirty bits cleaning, so it is the\\n * responsibility of the caller to make sure that the higher 96 bits of the `account` parameter are clean.\\n * @param token The IERC20 token contract for which the balance will be fetched.\\n * @param account The address of the account whose token balance will be fetched.\\n * @return tokenBalance The balance of the specified ERC20 token held by the account.\\n */\\n function safeBalanceOf(\\n IERC20 token,\\n address account\\n ) internal view returns(uint256 tokenBalance) {\\n bytes4 selector = IERC20.balanceOf.selector;\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n mstore(0x00, selector)\\n mstore(0x04, account)\\n let success := staticcall(gas(), token, 0x00, 0x24, 0x00, 0x20)\\n tokenBalance := mload(0)\\n\\n if or(iszero(success), lt(returndatasize(), 0x20)) {\\n let ptr := mload(0x40)\\n returndatacopy(ptr, 0, returndatasize())\\n revert(ptr, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Attempts to safely transfer tokens from one address to another.\\n * @dev If permit2 is true, uses the Permit2 standard; otherwise uses the standard ERC20 transferFrom.\\n * Either requires `true` in return data, or requires target to be smart-contract and empty return data.\\n * Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of\\n * the caller to make sure that the higher 96 bits of the `from` and `to` parameters are clean.\\n * @param token The IERC20 token contract from which the tokens will be transferred.\\n * @param from The address from which the tokens will be transferred.\\n * @param to The address to which the tokens will be transferred.\\n * @param amount The amount of tokens to transfer.\\n * @param permit2 If true, uses the Permit2 standard for the transfer; otherwise uses the standard ERC20 transferFrom.\\n */\\n function safeTransferFromUniversal(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 amount,\\n bool permit2\\n ) internal {\\n if (permit2) {\\n safeTransferFromPermit2(token, from, to, amount);\\n } else {\\n safeTransferFrom(token, from, to, amount);\\n }\\n }\\n\\n /**\\n * @notice Attempts to safely transfer tokens from one address to another using the ERC20 standard.\\n * @dev Either requires `true` in return data, or requires target to be smart-contract and empty return data.\\n * Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of\\n * the caller to make sure that the higher 96 bits of the `from` and `to` parameters are clean.\\n * @param token The IERC20 token contract from which the tokens will be transferred.\\n * @param from The address from which the tokens will be transferred.\\n * @param to The address to which the tokens will be transferred.\\n * @param amount The amount of tokens to transfer.\\n */\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 amount\\n ) internal {\\n bytes4 selector = token.transferFrom.selector;\\n bool success;\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n let data := mload(0x40)\\n\\n mstore(data, selector)\\n mstore(add(data, 0x04), from)\\n mstore(add(data, 0x24), to)\\n mstore(add(data, 0x44), amount)\\n success := call(gas(), token, 0, data, 100, 0x0, 0x20)\\n if success {\\n switch returndatasize()\\n case 0 {\\n success := gt(extcodesize(token), 0)\\n }\\n default {\\n success := and(gt(returndatasize(), 31), eq(mload(0), 1))\\n }\\n }\\n }\\n if (!success) revert SafeTransferFromFailed();\\n }\\n\\n /**\\n * @notice Attempts to safely transfer tokens from one address to another using the Permit2 standard.\\n * @dev Either requires `true` in return data, or requires target to be smart-contract and empty return data.\\n * Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of\\n * the caller to make sure that the higher 96 bits of the `from` and `to` parameters are clean.\\n * @param token The IERC20 token contract from which the tokens will be transferred.\\n * @param from The address from which the tokens will be transferred.\\n * @param to The address to which the tokens will be transferred.\\n * @param amount The amount of tokens to transfer.\\n */\\n function safeTransferFromPermit2(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 amount\\n ) internal {\\n if (amount > type(uint160).max) revert Permit2TransferAmountTooHigh();\\n bytes4 selector = IPermit2.transferFrom.selector;\\n bool success;\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n let data := mload(0x40)\\n\\n mstore(data, selector)\\n mstore(add(data, 0x04), from)\\n mstore(add(data, 0x24), to)\\n mstore(add(data, 0x44), amount)\\n mstore(add(data, 0x64), token)\\n success := call(gas(), _PERMIT2, 0, data, 0x84, 0x0, 0x0)\\n if success {\\n success := gt(extcodesize(_PERMIT2), 0)\\n }\\n }\\n if (!success) revert SafeTransferFromFailed();\\n }\\n\\n /**\\n * @notice Attempts to safely transfer tokens to another address.\\n * @dev Either requires `true` in return data, or requires target to be smart-contract and empty return data.\\n * Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of\\n * the caller to make sure that the higher 96 bits of the `to` parameter are clean.\\n * @param token The IERC20 token contract from which the tokens will be transferred.\\n * @param to The address to which the tokens will be transferred.\\n * @param value The amount of tokens to transfer.\\n */\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n if (!_makeCall(token, token.transfer.selector, to, value)) {\\n revert SafeTransferFailed();\\n }\\n }\\n\\n /**\\n * @notice Attempts to approve a spender to spend a certain amount of tokens.\\n * @dev If `approve(from, to, amount)` fails, it tries to set the allowance to zero, and retries the `approve` call.\\n * Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of\\n * the caller to make sure that the higher 96 bits of the `spender` parameter are clean.\\n * @param token The IERC20 token contract on which the call will be made.\\n * @param spender The address which will spend the funds.\\n * @param value The amount of tokens to be spent.\\n */\\n function forceApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n if (!_makeCall(token, token.approve.selector, spender, value)) {\\n if (\\n !_makeCall(token, token.approve.selector, spender, 0) ||\\n !_makeCall(token, token.approve.selector, spender, value)\\n ) {\\n revert ForceApproveFailed();\\n }\\n }\\n }\\n\\n /**\\n * @notice Safely increases the allowance of a spender.\\n * @dev Increases with safe math check. Checks if the increased allowance will overflow, if yes, then it reverts the transaction.\\n * Then uses `forceApprove` to increase the allowance.\\n * Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of\\n * the caller to make sure that the higher 96 bits of the `spender` parameter are clean.\\n * @param token The IERC20 token contract on which the call will be made.\\n * @param spender The address which will spend the funds.\\n * @param value The amount of tokens to increase the allowance by.\\n */\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 allowance = token.allowance(address(this), spender);\\n if (value > type(uint256).max - allowance) revert SafeIncreaseAllowanceFailed();\\n forceApprove(token, spender, allowance + value);\\n }\\n\\n /**\\n * @notice Safely decreases the allowance of a spender.\\n * @dev Decreases with safe math check. Checks if the decreased allowance will underflow, if yes, then it reverts the transaction.\\n * Then uses `forceApprove` to increase the allowance.\\n * Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of\\n * the caller to make sure that the higher 96 bits of the `spender` parameter are clean.\\n * @param token The IERC20 token contract on which the call will be made.\\n * @param spender The address which will spend the funds.\\n * @param value The amount of tokens to decrease the allowance by.\\n */\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 allowance = token.allowance(address(this), spender);\\n if (value > allowance) revert SafeDecreaseAllowanceFailed();\\n forceApprove(token, spender, allowance - value);\\n }\\n\\n /**\\n * @notice Attempts to execute the `permit` function on the provided token with the sender and contract as parameters.\\n * Permit type is determined automatically based on permit calldata (IERC20Permit, IDaiLikePermit, and IPermit2).\\n * @dev Wraps `tryPermit` function and forwards revert reason if permit fails.\\n * @param token The IERC20 token to execute the permit function on.\\n * @param permit The permit data to be used in the function call.\\n */\\n function safePermit(IERC20 token, bytes calldata permit) internal {\\n if (!tryPermit(token, msg.sender, address(this), permit)) RevertReasonForwarder.reRevert();\\n }\\n\\n /**\\n * @notice Attempts to execute the `permit` function on the provided token with custom owner and spender parameters.\\n * Permit type is determined automatically based on permit calldata (IERC20Permit, IDaiLikePermit, and IPermit2).\\n * @dev Wraps `tryPermit` function and forwards revert reason if permit fails.\\n * Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of\\n * the caller to make sure that the higher 96 bits of the `owner` and `spender` parameters are clean.\\n * @param token The IERC20 token to execute the permit function on.\\n * @param owner The owner of the tokens for which the permit is made.\\n * @param spender The spender allowed to spend the tokens by the permit.\\n * @param permit The permit data to be used in the function call.\\n */\\n function safePermit(IERC20 token, address owner, address spender, bytes calldata permit) internal {\\n if (!tryPermit(token, owner, spender, permit)) RevertReasonForwarder.reRevert();\\n }\\n\\n /**\\n * @notice Attempts to execute the `permit` function on the provided token with the sender and contract as parameters.\\n * @dev Invokes `tryPermit` with sender as owner and contract as spender.\\n * @param token The IERC20 token to execute the permit function on.\\n * @param permit The permit data to be used in the function call.\\n * @return success Returns true if the permit function was successfully executed, false otherwise.\\n */\\n function tryPermit(IERC20 token, bytes calldata permit) internal returns(bool success) {\\n return tryPermit(token, msg.sender, address(this), permit);\\n }\\n\\n /**\\n * @notice The function attempts to call the permit function on a given ERC20 token.\\n * @dev The function is designed to support a variety of permit functions, namely: IERC20Permit, IDaiLikePermit, IERC7597Permit and IPermit2.\\n * It accommodates both Compact and Full formats of these permit types.\\n * Please note, it is expected that the `expiration` parameter for the compact Permit2 and the `deadline` parameter\\n * for the compact Permit are to be incremented by one before invoking this function. This approach is motivated by\\n * gas efficiency considerations; as the unlimited expiration period is likely to be the most common scenario, and\\n * zeros are cheaper to pass in terms of gas cost. Thus, callers should increment the expiration or deadline by one\\n * before invocation for optimized performance.\\n * Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of\\n * the caller to make sure that the higher 96 bits of the `owner` and `spender` parameters are clean.\\n * @param token The address of the ERC20 token on which to call the permit function.\\n * @param owner The owner of the tokens. This address should have signed the off-chain permit.\\n * @param spender The address which will be approved for transfer of tokens.\\n * @param permit The off-chain permit data, containing different fields depending on the type of permit function.\\n * @return success A boolean indicating whether the permit call was successful.\\n */\\n function tryPermit(IERC20 token, address owner, address spender, bytes calldata permit) internal returns(bool success) {\\n // load function selectors for different permit standards\\n bytes4 permitSelector = IERC20Permit.permit.selector;\\n bytes4 daiPermitSelector = IDaiLikePermit.permit.selector;\\n bytes4 permit2Selector = IPermit2.permit.selector;\\n bytes4 erc7597PermitSelector = IERC7597Permit.permit.selector;\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n let ptr := mload(0x40)\\n\\n // Switch case for different permit lengths, indicating different permit standards\\n switch permit.length\\n // Compact IERC20Permit\\n case 100 {\\n mstore(ptr, permitSelector) // store selector\\n mstore(add(ptr, 0x04), owner) // store owner\\n mstore(add(ptr, 0x24), spender) // store spender\\n\\n // Compact IERC20Permit.permit(uint256 value, uint32 deadline, uint256 r, uint256 vs)\\n { // stack too deep\\n let deadline := shr(224, calldataload(add(permit.offset, 0x20))) // loads permit.offset 0x20..0x23\\n let vs := calldataload(add(permit.offset, 0x44)) // loads permit.offset 0x44..0x63\\n\\n calldatacopy(add(ptr, 0x44), permit.offset, 0x20) // store value = copy permit.offset 0x00..0x19\\n mstore(add(ptr, 0x64), sub(deadline, 1)) // store deadline = deadline - 1\\n mstore(add(ptr, 0x84), add(27, shr(255, vs))) // store v = most significant bit of vs + 27 (27 or 28)\\n calldatacopy(add(ptr, 0xa4), add(permit.offset, 0x24), 0x20) // store r = copy permit.offset 0x24..0x43\\n mstore(add(ptr, 0xc4), shr(1, shl(1, vs))) // store s = vs without most significant bit\\n }\\n // IERC20Permit.permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)\\n success := call(gas(), token, 0, ptr, 0xe4, 0, 0)\\n }\\n // Compact IDaiLikePermit\\n case 72 {\\n mstore(ptr, daiPermitSelector) // store selector\\n mstore(add(ptr, 0x04), owner) // store owner\\n mstore(add(ptr, 0x24), spender) // store spender\\n\\n // Compact IDaiLikePermit.permit(uint32 nonce, uint32 expiry, uint256 r, uint256 vs)\\n { // stack too deep\\n let expiry := shr(224, calldataload(add(permit.offset, 0x04))) // loads permit.offset 0x04..0x07\\n let vs := calldataload(add(permit.offset, 0x28)) // loads permit.offset 0x28..0x47\\n\\n mstore(add(ptr, 0x44), shr(224, calldataload(permit.offset))) // store nonce = copy permit.offset 0x00..0x03\\n mstore(add(ptr, 0x64), sub(expiry, 1)) // store expiry = expiry - 1\\n mstore(add(ptr, 0x84), true) // store allowed = true\\n mstore(add(ptr, 0xa4), add(27, shr(255, vs))) // store v = most significant bit of vs + 27 (27 or 28)\\n calldatacopy(add(ptr, 0xc4), add(permit.offset, 0x08), 0x20) // store r = copy permit.offset 0x08..0x27\\n mstore(add(ptr, 0xe4), shr(1, shl(1, vs))) // store s = vs without most significant bit\\n }\\n // IDaiLikePermit.permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s)\\n success := call(gas(), token, 0, ptr, 0x104, 0, 0)\\n }\\n // IERC20Permit\\n case 224 {\\n mstore(ptr, permitSelector)\\n calldatacopy(add(ptr, 0x04), permit.offset, permit.length) // copy permit calldata\\n // IERC20Permit.permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)\\n success := call(gas(), token, 0, ptr, 0xe4, 0, 0)\\n }\\n // IDaiLikePermit\\n case 256 {\\n mstore(ptr, daiPermitSelector)\\n calldatacopy(add(ptr, 0x04), permit.offset, permit.length) // copy permit calldata\\n // IDaiLikePermit.permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s)\\n success := call(gas(), token, 0, ptr, 0x104, 0, 0)\\n }\\n // Compact IPermit2\\n case 96 {\\n // Compact IPermit2.permit(uint160 amount, uint32 expiration, uint32 nonce, uint32 sigDeadline, uint256 r, uint256 vs)\\n mstore(ptr, permit2Selector) // store selector\\n mstore(add(ptr, 0x04), owner) // store owner\\n mstore(add(ptr, 0x24), token) // store token\\n\\n calldatacopy(add(ptr, 0x50), permit.offset, 0x14) // store amount = copy permit.offset 0x00..0x13\\n // and(0xffffffffffff, ...) - conversion to uint48\\n mstore(add(ptr, 0x64), and(0xffffffffffff, sub(shr(224, calldataload(add(permit.offset, 0x14))), 1))) // store expiration = ((permit.offset 0x14..0x17 - 1) & 0xffffffffffff)\\n mstore(add(ptr, 0x84), shr(224, calldataload(add(permit.offset, 0x18)))) // store nonce = copy permit.offset 0x18..0x1b\\n mstore(add(ptr, 0xa4), spender) // store spender\\n // and(0xffffffffffff, ...) - conversion to uint48\\n mstore(add(ptr, 0xc4), and(0xffffffffffff, sub(shr(224, calldataload(add(permit.offset, 0x1c))), 1))) // store sigDeadline = ((permit.offset 0x1c..0x1f - 1) & 0xffffffffffff)\\n mstore(add(ptr, 0xe4), 0x100) // store offset = 256\\n mstore(add(ptr, 0x104), 0x40) // store length = 64\\n calldatacopy(add(ptr, 0x124), add(permit.offset, 0x20), 0x20) // store r = copy permit.offset 0x20..0x3f\\n calldatacopy(add(ptr, 0x144), add(permit.offset, 0x40), 0x20) // store vs = copy permit.offset 0x40..0x5f\\n // IPermit2.permit(address owner, PermitSingle calldata permitSingle, bytes calldata signature)\\n success := call(gas(), _PERMIT2, 0, ptr, 0x164, 0, 0)\\n }\\n // IPermit2\\n case 352 {\\n mstore(ptr, permit2Selector)\\n calldatacopy(add(ptr, 0x04), permit.offset, permit.length) // copy permit calldata\\n // IPermit2.permit(address owner, PermitSingle calldata permitSingle, bytes calldata signature)\\n success := call(gas(), _PERMIT2, 0, ptr, 0x164, 0, 0)\\n }\\n // Dynamic length\\n default {\\n mstore(ptr, erc7597PermitSelector)\\n calldatacopy(add(ptr, 0x04), permit.offset, permit.length) // copy permit calldata\\n // IERC7597Permit.permit(address owner, address spender, uint256 value, uint256 deadline, bytes memory signature)\\n success := call(gas(), token, 0, ptr, add(permit.length, 4), 0, 0)\\n }\\n }\\n }\\n\\n /**\\n * @dev Executes a low level call to a token contract, making it resistant to reversion and erroneous boolean returns.\\n * @param token The IERC20 token contract on which the call will be made.\\n * @param selector The function signature that is to be called on the token contract.\\n * @param to The address to which the token amount will be transferred.\\n * @param amount The token amount to be transferred.\\n * @return success A boolean indicating if the call was successful. Returns 'true' on success and 'false' on failure.\\n * In case of success but no returned data, validates that the contract code exists.\\n * In case of returned data, ensures that it's a boolean `true`.\\n */\\n function _makeCall(\\n IERC20 token,\\n bytes4 selector,\\n address to,\\n uint256 amount\\n ) private returns (bool success) {\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n let data := mload(0x40)\\n\\n mstore(data, selector)\\n mstore(add(data, 0x04), to)\\n mstore(add(data, 0x24), amount)\\n success := call(gas(), token, 0, data, 0x44, 0x0, 0x20)\\n if success {\\n switch returndatasize()\\n case 0 {\\n success := gt(extcodesize(token), 0)\\n }\\n default {\\n success := and(gt(returndatasize(), 31), eq(mload(0), 1))\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Safely deposits a specified amount of Ether into the IWETH contract. Consumes less gas then regular `IWETH.deposit`.\\n * @param weth The IWETH token contract.\\n * @param amount The amount of Ether to deposit into the IWETH contract.\\n */\\n function safeDeposit(IWETH weth, uint256 amount) internal {\\n if (amount > 0) {\\n bytes4 selector = IWETH.deposit.selector;\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n mstore(0, selector)\\n if iszero(call(gas(), weth, amount, 0, 4, 0, 0)) {\\n let ptr := mload(0x40)\\n returndatacopy(ptr, 0, returndatasize())\\n revert(ptr, returndatasize())\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Safely withdraws a specified amount of wrapped Ether from the IWETH contract. Consumes less gas then regular `IWETH.withdraw`.\\n * @dev Uses inline assembly to interact with the IWETH contract.\\n * @param weth The IWETH token contract.\\n * @param amount The amount of wrapped Ether to withdraw from the IWETH contract.\\n */\\n function safeWithdraw(IWETH weth, uint256 amount) internal {\\n bytes4 selector = IWETH.withdraw.selector;\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n mstore(0, selector)\\n mstore(4, amount)\\n if iszero(call(gas(), weth, 0, 0, 0x24, 0, 0)) {\\n let ptr := mload(0x40)\\n returndatacopy(ptr, 0, returndatasize())\\n revert(ptr, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @notice Safely withdraws a specified amount of wrapped Ether from the IWETH contract to a specified recipient.\\n * Consumes less gas then regular `IWETH.withdraw`.\\n * @param weth The IWETH token contract.\\n * @param amount The amount of wrapped Ether to withdraw from the IWETH contract.\\n * @param to The recipient of the withdrawn Ether.\\n */\\n function safeWithdrawTo(IWETH weth, uint256 amount, address to) internal {\\n safeWithdraw(weth, amount);\\n if (to != address(this)) {\\n assembly (\\\"memory-safe\\\") { // solhint-disable-line no-inline-assembly\\n if iszero(call(_RAW_CALL_GAS_LIMIT, to, amount, 0, 0, 0, 0)) {\\n let ptr := mload(0x40)\\n returndatacopy(ptr, 0, returndatasize())\\n revert(ptr, returndatasize())\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5010526a91c8fe876a0959e952186156a0c8f1888bf392eb406a93f449b2716\",\"license\":\"MIT\"},\"@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/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x85a45f3f10014a0f8be41157a32b6a5f905753ea64a4b64e29fc12b7deeecf39\",\"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 ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the 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\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\"},\"@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 ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\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\",\"keccak256\":\"0x6008dabfe393240d73d7dd7688033f72740d570aa422254d29a7dce8568f3aff\",\"license\":\"MIT\"},\"@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\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev The ETH balance of the account is not enough to perform the operation.\\n */\\n error AddressInsufficientBalance(address account);\\n\\n /**\\n * @dev There's no code at `target` (it is not a contract).\\n */\\n error AddressEmptyCode(address target);\\n\\n /**\\n * @dev A call to an address target failed. The target may have reverted.\\n */\\n error FailedInnerCall();\\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 AddressInsufficientBalance(address(this));\\n }\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n if (!success) {\\n revert FailedInnerCall();\\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 * {FailedInnerCall} 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 AddressInsufficientBalance(address(this));\\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 {FailedInnerCall}) in case of an\\n * 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 {FailedInnerCall} 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 {FailedInnerCall}.\\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 FailedInnerCall();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaf28a975a78550e45f65e559a3ad6a5ad43b9b8a37366999abd1b7084eb70721\",\"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/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Muldiv operation overflow.\\n */\\n error MathOverflowedMulDiv();\\n\\n enum Rounding {\\n Floor, // Toward negative infinity\\n Ceil, // Toward positive infinity\\n Trunc, // Toward zero\\n Expand // Away from zero\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds towards infinity instead\\n * of rounding towards zero.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (b == 0) {\\n // Guarantee the same behavior as in a regular Solidity division.\\n return a / b;\\n }\\n\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\\n * denominator == 0.\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\\n * Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0 = x * y; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (denominator <= prod1) {\\n revert MathOverflowedMulDiv();\\n }\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\\n // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\\n\\n uint256 twos = denominator & (0 - denominator);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\\n // works in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\\n * towards zero.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2 of a positive value rounded towards zero.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10 of a positive value rounded towards zero.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10 ** 64) {\\n value /= 10 ** 64;\\n result += 64;\\n }\\n if (value >= 10 ** 32) {\\n value /= 10 ** 32;\\n result += 32;\\n }\\n if (value >= 10 ** 16) {\\n value /= 10 ** 16;\\n result += 16;\\n }\\n if (value >= 10 ** 8) {\\n value /= 10 ** 8;\\n result += 8;\\n }\\n if (value >= 10 ** 4) {\\n value /= 10 ** 4;\\n result += 4;\\n }\\n if (value >= 10 ** 2) {\\n value /= 10 ** 2;\\n result += 2;\\n }\\n if (value >= 10 ** 1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256 of a positive value rounded towards zero.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\\n */\\n function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\\n return uint8(rounding) % 2 == 1;\\n }\\n}\\n\",\"keccak256\":\"0x005ec64c6313f0555d59e278f9a7a5ab2db5bdc72a027f255a37c327af1ec02d\",\"license\":\"MIT\"},\"contracts/SignatureMerkleDrop128.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.23;\\n\\nimport { Math } from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { SafeERC20, IERC20 } from \\\"@1inch/solidity-utils/contracts/libraries/SafeERC20.sol\\\";\\nimport { ECDSA } from \\\"@1inch/solidity-utils/contracts/libraries/ECDSA.sol\\\";\\n\\nimport { ISignatureMerkleDrop128 } from \\\"./interfaces/ISignatureMerkleDrop128.sol\\\";\\n\\ncontract SignatureMerkleDrop128 is ISignatureMerkleDrop128, Ownable {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n /* solhint-disable immutable-vars-naming */\\n address public immutable override token;\\n bytes16 public immutable override merkleRoot;\\n uint256 public immutable override depth;\\n /* solhint-enable immutable-vars-naming */\\n\\n // This is a packed array of booleans.\\n mapping(uint256 => uint256) private _claimedBitMap;\\n\\n uint256 private constant _CLAIM_GAS_COST = 60000;\\n\\n receive() external payable {} // solhint-disable-line no-empty-blocks\\n\\n constructor(address token_, bytes16 merkleRoot_, uint256 depth_) Ownable(msg.sender) {\\n token = token_;\\n merkleRoot = merkleRoot_;\\n depth = depth_;\\n }\\n\\n function claim(address receiver, uint256 amount, bytes calldata merkleProof, bytes calldata signature) external override {\\n bytes32 signedHash = ECDSA.toEthSignedMessageHash(keccak256(abi.encodePacked(receiver)));\\n address account = ECDSA.recover(signedHash, signature);\\n // Verify the merkle proof.\\n bytes16 node = bytes16(keccak256(abi.encodePacked(account, amount)));\\n (bool valid, uint256 index) = _verifyAsm(merkleProof, merkleRoot, node);\\n if (!valid) revert InvalidProof();\\n _invalidate(index);\\n IERC20(token).safeTransfer(receiver, amount);\\n _cashback();\\n }\\n\\n function verify(bytes calldata proof, bytes16 root, bytes16 leaf) external view returns (bool valid, uint256 index) {\\n return _verifyAsm(proof, root, leaf);\\n }\\n\\n function verify(bytes calldata proof, bytes16 leaf) external view returns (bool valid, uint256 index) {\\n return _verifyAsm(proof, merkleRoot, leaf);\\n }\\n\\n function isClaimed(uint256 index) external view override returns (bool) {\\n uint256 claimedWordIndex = index / 256;\\n uint256 claimedBitIndex = index % 256;\\n uint256 claimedWord = _claimedBitMap[claimedWordIndex];\\n uint256 mask = (1 << claimedBitIndex);\\n return claimedWord & mask == mask;\\n }\\n\\n function _cashback() private {\\n uint256 balance = address(this).balance;\\n if (balance > 0) {\\n // solhint-disable-next-line avoid-tx-origin\\n payable(tx.origin).sendValue(Math.min(block.basefee * _CLAIM_GAS_COST, balance));\\n }\\n }\\n\\n function _invalidate(uint256 index) private {\\n uint256 claimedWordIndex = index >> 8;\\n uint256 claimedBitIndex = index & 0xff;\\n uint256 claimedWord = _claimedBitMap[claimedWordIndex];\\n uint256 newClaimedWord = claimedWord | (1 << claimedBitIndex);\\n if (claimedWord == newClaimedWord) revert DropAlreadyClaimed();\\n _claimedBitMap[claimedWordIndex] = newClaimedWord;\\n }\\n\\n function _verifyAsm(bytes calldata proof, bytes16 root, bytes16 leaf) private view returns (bool valid, uint256 index) {\\n /// @solidity memory-safe-assembly\\n assembly { // solhint-disable-line no-inline-assembly\\n let ptr := proof.offset\\n let mask := 1\\n\\n for { let end := add(ptr, proof.length) } lt(ptr, end) { ptr := add(ptr, 0x10) } {\\n let node := calldataload(ptr)\\n\\n switch lt(leaf, node)\\n case 1 {\\n mstore(0x00, leaf)\\n mstore(0x10, node)\\n }\\n default {\\n mstore(0x00, node)\\n mstore(0x10, leaf)\\n index := or(mask, index)\\n }\\n\\n leaf := keccak256(0x00, 0x20)\\n mask := shl(1, mask)\\n }\\n\\n valid := iszero(shr(128, xor(root, leaf)))\\n }\\n unchecked {\\n index <<= depth - proof.length / 16;\\n }\\n }\\n\\n function rescueFunds(address token_, uint256 amount) external onlyOwner {\\n if (token_ == address(0)) {\\n payable(msg.sender).sendValue(amount);\\n } else {\\n IERC20(token_).safeTransfer(msg.sender, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x37f4604f757e124412bdd26b92d78e5770a7314d3cb04e3b5207d58d3c60a25b\",\"license\":\"MIT\"},\"contracts/interfaces/ISignatureMerkleDrop128.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\npragma abicoder v1;\\n\\n// Allows anyone to claim a token if they exist in a merkle root.\\ninterface ISignatureMerkleDrop128 {\\n error InvalidProof();\\n error DropAlreadyClaimed();\\n\\n // Returns the address of the token distributed by this contract.\\n function token() external view returns (address);\\n // Returns the merkle root of the merkle tree containing account balances available to claim.\\n function merkleRoot() external view returns (bytes16);\\n // Returns the tree depth of the merkle tree containing account balances available to claim.\\n function depth() external view returns (uint256);\\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\\n function claim(address receiver, uint256 amount, bytes calldata merkleProof, bytes calldata signature) external;\\n // Verifies that given leaf and merkle proof matches given merkle root and returns leaf index.\\n function verify(bytes calldata proof, bytes16 root, bytes16 leaf) external view returns (bool valid, uint256 index);\\n // Returns true if the index has been marked claimed.\\n function isClaimed(uint256 index) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x761d213dd5c12d2301107331a4d05b822b575d506444454fd4b61436c657ec7a\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60e060405234801561000f575f80fd5b50604051610e96380380610e9683398101604081905261002e916100cf565b338061005357604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b61005c81610080565b506001600160a01b039092166080526001600160801b03191660a05260c052610126565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f805f606084860312156100e1575f80fd5b83516001600160a01b03811681146100f7575f80fd5b60208501519093506001600160801b031981168114610114575f80fd5b80925050604084015190509250925092565b60805160a05160c051610d2b61016b5f395f8181610176015261065301525f818160d70152818161036d01526104c901525f81816102c2015261054c0152610d2b5ff3fe6080604052600436106100bb575f3560e01c80638da5cb5b11610071578063b33302c71161004c578063b33302c714610273578063f2fde38b14610292578063fc0c546a146102b1575f80fd5b80638da5cb5b146101db5780638ebb005d146102255780639e34070f14610244575f80fd5b8063631c56ef116100a1578063631c56ef14610165578063715018a6146101a657806378e3214f146101bc575f80fd5b80632eb4a7ab146100c65780633956851b1461012f575f80fd5b366100c257005b5f80fd5b3480156100d1575f80fd5b506100f97f000000000000000000000000000000000000000000000000000000000000000081565b6040517fffffffffffffffffffffffffffffffff0000000000000000000000000000000090911681526020015b60405180910390f35b34801561013a575f80fd5b5061014e610149366004610ab6565b6102e4565b604080519215158352602083019190915201610126565b348015610170575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610126565b3480156101b1575f80fd5b506101ba6102ff565b005b3480156101c7575f80fd5b506101ba6101d6366004610b3a565b610312565b3480156101e6575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610126565b348015610230575f80fd5b5061014e61023f366004610b62565b610364565b34801561024f575f80fd5b5061026361025e366004610bb2565b61039e565b6040519015158152602001610126565b34801561027e575f80fd5b506101ba61028d366004610bc9565b6103dc565b34801561029d575f80fd5b506101ba6102ac366004610c4d565b610588565b3480156102bc575f80fd5b506102007f000000000000000000000000000000000000000000000000000000000000000081565b5f806102f2868686866105f0565b9150915094509492505050565b610307610679565b6103105f6106cb565b565b61031a610679565b73ffffffffffffffffffffffffffffffffffffffff82166103435761033f338261073f565b5050565b61033f73ffffffffffffffffffffffffffffffffffffffff83163383610816565b5f8061039285857f0000000000000000000000000000000000000000000000000000000000000000866105f0565b91509150935093915050565b5f806103ac61010084610c93565b90505f6103bb61010085610ca6565b5f9283526001602081905260409093205492901b9182169091149392505050565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660208201525f9061045c90603401604051602081830303815290604052805190602001207f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f908152601c91909152603c902090565b90505f61046a828585610878565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b166020820152603481018990529091505f906054016040516020818303038152906040528051906020012090505f806104ee89897f0000000000000000000000000000000000000000000000000000000000000000866105f0565b9150915081610529576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61053281610940565b61057373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168c8c610816565b61057b6109af565b5050505050505050505050565b610590610679565b73ffffffffffffffffffffffffffffffffffffffff81166105e4576040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081525f60048201526024015b60405180910390fd5b6105ed816106cb565b50565b5f808560018682015b808310156106405782358087106001811461061f57815f52876010528584179550610627565b875f52816010525b505060205f2095508160011b91506010830192506105f9565b5050509190921860801c159460109093047f0000000000000000000000000000000000000000000000000000000000000000031b925050565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610310576040517f118cdaa70000000000000000000000000000000000000000000000000000000081523360048201526024016105db565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8047101561077b576040517fcd7860590000000000000000000000000000000000000000000000000000000081523060048201526024016105db565b5f8273ffffffffffffffffffffffffffffffffffffffff16826040515f6040518083038185875af1925050503d805f81146107d1576040519150601f19603f3d011682016040523d82523d5f602084013e6107d6565b606091505b5050905080610811576040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b610842837fa9059cbb0000000000000000000000000000000000000000000000000000000084846109d5565b610811576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051826041811461089557604081146108ae575f91506108ef565b60408501355f1a602083015260408560408401376108ef565b60208501358060ff1c601b01602084015260208660408501377f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660608301525b508015610938577f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a160608201511015610938578481525f805260205f60808360015afa505f5191505b509392505050565b600881901c5f8181526001602081905260409091205460ff841691821b8117808203610998576040517f1e65ff1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f9384526001602052604090932092909255505050565b4780156105ed576105ed6109ce6109c861ea6048610cb9565b83610a24565b329061073f565b5f60405184815283600482015282602482015260205f6044835f8a5af19150508015610a1c573d8015610a135760015f5114601f3d11169150610a1a565b5f863b1191505b505b949350505050565b5f818310610a325781610a34565b825b90505b92915050565b5f8083601f840112610a4d575f80fd5b50813567ffffffffffffffff811115610a64575f80fd5b602083019150836020828501011115610a7b575f80fd5b9250929050565b80357fffffffffffffffffffffffffffffffff0000000000000000000000000000000081168114610ab1575f80fd5b919050565b5f805f8060608587031215610ac9575f80fd5b843567ffffffffffffffff811115610adf575f80fd5b610aeb87828801610a3d565b9095509350610afe905060208601610a82565b9150610b0c60408601610a82565b905092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff81168114610ab1575f80fd5b5f8060408385031215610b4b575f80fd5b610b5483610b17565b946020939093013593505050565b5f805f60408486031215610b74575f80fd5b833567ffffffffffffffff811115610b8a575f80fd5b610b9686828701610a3d565b9094509250610ba9905060208501610a82565b90509250925092565b5f60208284031215610bc2575f80fd5b5035919050565b5f805f805f8060808789031215610bde575f80fd5b610be787610b17565b955060208701359450604087013567ffffffffffffffff80821115610c0a575f80fd5b610c168a838b01610a3d565b90965094506060890135915080821115610c2e575f80fd5b50610c3b89828a01610a3d565b979a9699509497509295939492505050565b5f60208284031215610c5d575f80fd5b610a3482610b17565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f82610ca157610ca1610c66565b500490565b5f82610cb457610cb4610c66565b500690565b8082028115828204841417610a37577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffdfea2646970667358221220bcfb7109300f22437a7f2522f92947c9c5628d89f69b694516d9c47bbfc0854f64736f6c63430008170033", + "deployedBytecode": "0x6080604052600436106100bb575f3560e01c80638da5cb5b11610071578063b33302c71161004c578063b33302c714610273578063f2fde38b14610292578063fc0c546a146102b1575f80fd5b80638da5cb5b146101db5780638ebb005d146102255780639e34070f14610244575f80fd5b8063631c56ef116100a1578063631c56ef14610165578063715018a6146101a657806378e3214f146101bc575f80fd5b80632eb4a7ab146100c65780633956851b1461012f575f80fd5b366100c257005b5f80fd5b3480156100d1575f80fd5b506100f97f000000000000000000000000000000000000000000000000000000000000000081565b6040517fffffffffffffffffffffffffffffffff0000000000000000000000000000000090911681526020015b60405180910390f35b34801561013a575f80fd5b5061014e610149366004610ab6565b6102e4565b604080519215158352602083019190915201610126565b348015610170575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610126565b3480156101b1575f80fd5b506101ba6102ff565b005b3480156101c7575f80fd5b506101ba6101d6366004610b3a565b610312565b3480156101e6575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610126565b348015610230575f80fd5b5061014e61023f366004610b62565b610364565b34801561024f575f80fd5b5061026361025e366004610bb2565b61039e565b6040519015158152602001610126565b34801561027e575f80fd5b506101ba61028d366004610bc9565b6103dc565b34801561029d575f80fd5b506101ba6102ac366004610c4d565b610588565b3480156102bc575f80fd5b506102007f000000000000000000000000000000000000000000000000000000000000000081565b5f806102f2868686866105f0565b9150915094509492505050565b610307610679565b6103105f6106cb565b565b61031a610679565b73ffffffffffffffffffffffffffffffffffffffff82166103435761033f338261073f565b5050565b61033f73ffffffffffffffffffffffffffffffffffffffff83163383610816565b5f8061039285857f0000000000000000000000000000000000000000000000000000000000000000866105f0565b91509150935093915050565b5f806103ac61010084610c93565b90505f6103bb61010085610ca6565b5f9283526001602081905260409093205492901b9182169091149392505050565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660208201525f9061045c90603401604051602081830303815290604052805190602001207f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f908152601c91909152603c902090565b90505f61046a828585610878565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b166020820152603481018990529091505f906054016040516020818303038152906040528051906020012090505f806104ee89897f0000000000000000000000000000000000000000000000000000000000000000866105f0565b9150915081610529576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61053281610940565b61057373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168c8c610816565b61057b6109af565b5050505050505050505050565b610590610679565b73ffffffffffffffffffffffffffffffffffffffff81166105e4576040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081525f60048201526024015b60405180910390fd5b6105ed816106cb565b50565b5f808560018682015b808310156106405782358087106001811461061f57815f52876010528584179550610627565b875f52816010525b505060205f2095508160011b91506010830192506105f9565b5050509190921860801c159460109093047f0000000000000000000000000000000000000000000000000000000000000000031b925050565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610310576040517f118cdaa70000000000000000000000000000000000000000000000000000000081523360048201526024016105db565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8047101561077b576040517fcd7860590000000000000000000000000000000000000000000000000000000081523060048201526024016105db565b5f8273ffffffffffffffffffffffffffffffffffffffff16826040515f6040518083038185875af1925050503d805f81146107d1576040519150601f19603f3d011682016040523d82523d5f602084013e6107d6565b606091505b5050905080610811576040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b610842837fa9059cbb0000000000000000000000000000000000000000000000000000000084846109d5565b610811576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051826041811461089557604081146108ae575f91506108ef565b60408501355f1a602083015260408560408401376108ef565b60208501358060ff1c601b01602084015260208660408501377f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660608301525b508015610938577f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a160608201511015610938578481525f805260205f60808360015afa505f5191505b509392505050565b600881901c5f8181526001602081905260409091205460ff841691821b8117808203610998576040517f1e65ff1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f9384526001602052604090932092909255505050565b4780156105ed576105ed6109ce6109c861ea6048610cb9565b83610a24565b329061073f565b5f60405184815283600482015282602482015260205f6044835f8a5af19150508015610a1c573d8015610a135760015f5114601f3d11169150610a1a565b5f863b1191505b505b949350505050565b5f818310610a325781610a34565b825b90505b92915050565b5f8083601f840112610a4d575f80fd5b50813567ffffffffffffffff811115610a64575f80fd5b602083019150836020828501011115610a7b575f80fd5b9250929050565b80357fffffffffffffffffffffffffffffffff0000000000000000000000000000000081168114610ab1575f80fd5b919050565b5f805f8060608587031215610ac9575f80fd5b843567ffffffffffffffff811115610adf575f80fd5b610aeb87828801610a3d565b9095509350610afe905060208601610a82565b9150610b0c60408601610a82565b905092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff81168114610ab1575f80fd5b5f8060408385031215610b4b575f80fd5b610b5483610b17565b946020939093013593505050565b5f805f60408486031215610b74575f80fd5b833567ffffffffffffffff811115610b8a575f80fd5b610b9686828701610a3d565b9094509250610ba9905060208501610a82565b90509250925092565b5f60208284031215610bc2575f80fd5b5035919050565b5f805f805f8060808789031215610bde575f80fd5b610be787610b17565b955060208701359450604087013567ffffffffffffffff80821115610c0a575f80fd5b610c168a838b01610a3d565b90965094506060890135915080821115610c2e575f80fd5b50610c3b89828a01610a3d565b979a9699509497509295939492505050565b5f60208284031215610c5d575f80fd5b610a3482610b17565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f82610ca157610ca1610c66565b500490565b5f82610cb457610cb4610c66565b500690565b8082028115828204841417610a37577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffdfea2646970667358221220bcfb7109300f22437a7f2522f92947c9c5628d89f69b694516d9c47bbfc0854f64736f6c63430008170033", + "devdoc": { + "errors": { + "AddressInsufficientBalance(address)": [ + { + "details": "The ETH balance of the account is not enough to perform the operation." + } + ], + "FailedInnerCall()": [ + { + "details": "A call to an address target failed. The target may have reverted." + } + ], + "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." + } + ] + }, + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current 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": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 1085, + "contract": "contracts/SignatureMerkleDrop128.sol:SignatureMerkleDrop128", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 3719, + "contract": "contracts/SignatureMerkleDrop128.sol:SignatureMerkleDrop128", + "label": "_claimedBitMap", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_uint256,t_uint256)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_uint256,t_uint256)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/src/.latest b/src/.latest index ac4213d6..d2e1cefe 100644 --- a/src/.latest +++ b/src/.latest @@ -1 +1 @@ -43 \ No newline at end of file +44 \ No newline at end of file