diff --git a/gsn/deploy/config/keys/keys.dev.json b/gsn/deploy/config/keys/keys.dev.json new file mode 100644 index 00000000..f3068cea --- /dev/null +++ b/gsn/deploy/config/keys/keys.dev.json @@ -0,0 +1,3 @@ +[ + "8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba" +] \ No newline at end of file diff --git a/gsn/deploy/data/deployments/amoy/.chainId b/gsn/deploy/data/deployments/amoy/.chainId new file mode 100644 index 00000000..b8ca3095 --- /dev/null +++ b/gsn/deploy/data/deployments/amoy/.chainId @@ -0,0 +1 @@ +80002 \ No newline at end of file diff --git a/gsn/deploy/data/deployments/amoy/Forwarder.json b/gsn/deploy/data/deployments/amoy/Forwarder.json new file mode 100644 index 00000000..2066f6a5 --- /dev/null +++ b/gsn/deploy/data/deployments/amoy/Forwarder.json @@ -0,0 +1,587 @@ +{ + "address": "0x985999389f85E5eA4425ac7379b1F7D56e694785", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "domainSeparator", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "domainValue", + "type": "bytes" + } + ], + "name": "DomainRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "typeHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "string", + "name": "typeStr", + "type": "string" + } + ], + "name": "RequestTypeRegistered", + "type": "event" + }, + { + "inputs": [], + "name": "EIP712_DOMAIN_TYPE", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GENERIC_PARAMS", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "validUntilTime", + "type": "uint256" + } + ], + "internalType": "struct IForwarder.ForwardRequest", + "name": "req", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "requestTypeHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "suffixData", + "type": "bytes" + } + ], + "name": "_getEncoded", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "domains", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "validUntilTime", + "type": "uint256" + } + ], + "internalType": "struct IForwarder.ForwardRequest", + "name": "req", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "domainSeparator", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "requestTypeHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "suffixData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "sig", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "ret", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + } + ], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + } + ], + "name": "registerDomainSeparator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "typeName", + "type": "string" + }, + { + "internalType": "string", + "name": "typeSuffix", + "type": "string" + } + ], + "name": "registerRequestType", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "typeHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "validUntilTime", + "type": "uint256" + } + ], + "internalType": "struct IForwarder.ForwardRequest", + "name": "req", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "domainSeparator", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "requestTypeHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "suffixData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "sig", + "type": "bytes" + } + ], + "name": "verify", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x1a2373b4ebf2b3e513267b463cf077f43e5a71f9011a3b0b40c4d6467f71388a", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x61B1E290d2F465d6667336d4934941aa2517AfA2", + "contractAddress": null, + "transactionIndex": 0, + "gasUsed": "1198078", + "logsBloom": "0x00000000000000000008000000000000000000000000000000000000000000000000001000000002000000000000000000008000000800000000000000000000000000000000100000000000000000800000000000000000000100000000000000000000202000000000000000000000004000000000000080000000000000000000000000000000800000000000000000000000000000000000000000000000202008000000000000000000000000000020000000000000000000000000004000000000000000008001000000000000000000000000000000100000000000000000000000000000000000000800000040000000000000000000000000100000", + "blockHash": "0x1c69cb0f30e645a9d167fab5e5326bbf70f32c4d7ebe9a72b25af17afc1dd268", + "transactionHash": "0x1a2373b4ebf2b3e513267b463cf077f43e5a71f9011a3b0b40c4d6467f71388a", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 4880192, + "transactionHash": "0x1a2373b4ebf2b3e513267b463cf077f43e5a71f9011a3b0b40c4d6467f71388a", + "address": "0x985999389f85E5eA4425ac7379b1F7D56e694785", + "topics": [ + "0x64d6bce64323458c44643c51fe45113efc882082f7b7fd5f09f0d69d2eedb202", + "0xb91ae508e6f0e8e33913dec60d2fdcb39fe037ce56198c70a7927d7cd813fd96" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000071466f72776172645265717565737428616464726573732066726f6d2c6164647265737320746f2c75696e743235362076616c75652c75696e74323536206761732c75696e74323536206e6f6e63652c627974657320646174612c75696e743235362076616c6964556e74696c54696d6529000000000000000000000000000000", + "logIndex": 0, + "blockHash": "0x1c69cb0f30e645a9d167fab5e5326bbf70f32c4d7ebe9a72b25af17afc1dd268" + }, + { + "transactionIndex": 0, + "blockNumber": 4880192, + "transactionHash": "0x1a2373b4ebf2b3e513267b463cf077f43e5a71f9011a3b0b40c4d6467f71388a", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x00000000000000000000000061b1e290d2f465d6667336d4934941aa2517afa2", + "0x000000000000000000000000ac75d6efec891724b88b916b36e2ef38bcbec73f" + ], + "data": "0x00000000000000000000000000000000000000000000000000ff62bc4f1f181e000000000000000000000000000000000000000000000000064df88c8e40a800000000000000000000000000000000000000000000000017443e184f9015f0fa000000000000000000000000000000000000000000000000054e95d03f218fe2000000000000000000000000000000000000000000000017453d7b0bdf350918", + "logIndex": 1, + "blockHash": "0x1c69cb0f30e645a9d167fab5e5326bbf70f32c4d7ebe9a72b25af17afc1dd268" + } + ], + "blockNumber": 4880192, + "cumulativeGasUsed": "1198078", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "766eaa539015b343a6f8732a84d5a9ae", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"domainSeparator\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"domainValue\",\"type\":\"bytes\"}],\"name\":\"DomainRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"typeHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"typeStr\",\"type\":\"string\"}],\"name\":\"RequestTypeRegistered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"EIP712_DOMAIN_TYPE\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GENERIC_PARAMS\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"validUntilTime\",\"type\":\"uint256\"}],\"internalType\":\"struct IForwarder.ForwardRequest\",\"name\":\"req\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"requestTypeHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"suffixData\",\"type\":\"bytes\"}],\"name\":\"_getEncoded\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"domains\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"validUntilTime\",\"type\":\"uint256\"}],\"internalType\":\"struct IForwarder.ForwardRequest\",\"name\":\"req\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"domainSeparator\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"requestTypeHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"suffixData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sig\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"ret\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"name\":\"registerDomainSeparator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"typeName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"typeSuffix\",\"type\":\"string\"}],\"name\":\"registerRequestType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"typeHashes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"validUntilTime\",\"type\":\"uint256\"}],\"internalType\":\"struct IForwarder.ForwardRequest\",\"name\":\"req\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"domainSeparator\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"requestTypeHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"suffixData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sig\",\"type\":\"bytes\"}],\"name\":\"verify\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"execute((address,address,uint256,uint256,uint256,bytes,uint256),bytes32,bytes32,bytes,bytes)\":{\"params\":{\"domainSeparator\":\"The domain used when signing this request.\",\"forwardRequest\":\"All requested transaction parameters.\",\"requestTypeHash\":\"The request type used when signing this request.\",\"signature\":\"The client signature to be validated.\",\"suffixData\":\"The ABI-encoded extension data for the current `RequestType` used when signing this request.\"},\"returns\":{\"ret\":\"The byte array returned by the underlying `CALL` to the target address.\",\"success\":\"The success flag of the underlying `CALL` to the target address.\"}},\"getNonce(address)\":{\"params\":{\"from\":\"The address of a sender.\"},\"returns\":{\"_0\":\"The nonce for this address.\"}},\"registerDomainSeparator(string,string)\":{\"params\":{\"name\":\"The domain's display name.\",\"version\":\"The domain/protocol version.\"}},\"registerRequestType(string,string)\":{\"params\":{\"typeName\":\"The name of the request type.\",\"typeSuffix\":\"Any extra data after the generic params. Must contain add at least one param. The generic ForwardRequest type is always registered by the constructor.\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"title\":\"The Forwarder Implementation\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"_getEncoded((address,address,uint256,uint256,uint256,bytes,uint256),bytes32,bytes)\":{\"notice\":\"Creates a byte array that is a valid ABI encoding of a request of a `RequestType` type. See `execute()`.\"},\"execute((address,address,uint256,uint256,uint256,bytes,uint256),bytes32,bytes32,bytes,bytes)\":{\"notice\":\"Executes a transaction specified by the `ForwardRequest`. The transaction is first verified and then executed. The success flag and returned bytes array of the `CALL` are returned as-is. This method would revert only in case of a verification error. All the target errors are reported using the returned success flag and returned bytes array.\"},\"registerDomainSeparator(string,string)\":{\"notice\":\"Register a new domain separator.This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.The domain separator must have the following fields: `name`, `version`, `chainId`, `verifyingContract`. The `chainId` is the current network's `chainId`, and the `verifyingContract` is this Forwarder's address. This method accepts the domain name and version to create and register the domain separator value.\"},\"registerRequestType(string,string)\":{\"notice\":\"Register a new Request typehash.This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\"},\"verify((address,address,uint256,uint256,uint256,bytes,uint256),bytes32,bytes32,bytes,bytes)\":{\"notice\":\"Verify the transaction is valid and can be executed. Implementations must validate the signature and the nonce of the request are correct. Does not revert and returns successfully if the input is valid. Reverts if any validation has failed. For instance, if either signature or nonce are incorrect. Reverts if `domainSeparator` or `requestTypeHash` are not registered as well.\"}},\"notice\":\"This implementation of the `IForwarder` interface uses ERC-712 signatures and stored nonces for verification.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@opengsn/contracts/src/forwarder/Forwarder.sol\":\"Forwarder\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@opengsn/contracts/src/forwarder/Forwarder.sol\":{\"content\":\"// solhint-disable not-rely-on-time\\n// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\n\\n// #if ENABLE_CONSOLE_LOG\\nimport \\\"hardhat/console.sol\\\";\\n// #endif\\n\\nimport \\\"./IForwarder.sol\\\";\\n\\n/**\\n * @title The Forwarder Implementation\\n * @notice This implementation of the `IForwarder` interface uses ERC-712 signatures and stored nonces for verification.\\n */\\ncontract Forwarder is IForwarder, ERC165 {\\n using ECDSA for bytes32;\\n\\n address private constant DRY_RUN_ADDRESS = 0x0000000000000000000000000000000000000000;\\n\\n string public constant GENERIC_PARAMS = \\\"address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data,uint256 validUntilTime\\\";\\n\\n string public constant EIP712_DOMAIN_TYPE = \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\";\\n\\n mapping(bytes32 => bool) public typeHashes;\\n mapping(bytes32 => bool) public domains;\\n\\n // Nonces of senders, used to prevent replay attacks\\n mapping(address => uint256) private nonces;\\n\\n // solhint-disable-next-line no-empty-blocks\\n receive() external payable {}\\n\\n /// @inheritdoc IForwarder\\n function getNonce(address from)\\n public view override\\n returns (uint256) {\\n return nonces[from];\\n }\\n\\n constructor() {\\n string memory requestType = string(abi.encodePacked(\\\"ForwardRequest(\\\", GENERIC_PARAMS, \\\")\\\"));\\n registerRequestTypeInternal(requestType);\\n }\\n\\n /// @inheritdoc IERC165\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\\n return interfaceId == type(IForwarder).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /// @inheritdoc IForwarder\\n function verify(\\n ForwardRequest calldata req,\\n bytes32 domainSeparator,\\n bytes32 requestTypeHash,\\n bytes calldata suffixData,\\n bytes calldata sig)\\n external override view {\\n _verifyNonce(req);\\n _verifySig(req, domainSeparator, requestTypeHash, suffixData, sig);\\n }\\n\\n /// @inheritdoc IForwarder\\n function execute(\\n ForwardRequest calldata req,\\n bytes32 domainSeparator,\\n bytes32 requestTypeHash,\\n bytes calldata suffixData,\\n bytes calldata sig\\n )\\n external payable\\n override\\n returns (bool success, bytes memory ret) {\\n _verifySig(req, domainSeparator, requestTypeHash, suffixData, sig);\\n _verifyAndUpdateNonce(req);\\n\\n require(req.validUntilTime == 0 || req.validUntilTime > block.timestamp, \\\"FWD: request expired\\\");\\n\\n uint256 gasForTransfer = 0;\\n if ( req.value != 0 ) {\\n gasForTransfer = 40000; //buffer in case we need to move eth after the transaction.\\n }\\n bytes memory callData = abi.encodePacked(req.data, req.from);\\n require(gasleft()*63/64 >= req.gas + gasForTransfer, \\\"FWD: insufficient gas\\\");\\n // solhint-disable-next-line avoid-low-level-calls\\n (success,ret) = req.to.call{gas : req.gas, value : req.value}(callData);\\n\\n // #if ENABLE_CONSOLE_LOG\\n console.log(\\\"execute result: success: %s ret:\\\", success);\\n console.logBytes(ret);\\n // #endif\\n\\n if ( req.value != 0 && address(this).balance>0 ) {\\n // can't fail: req.from signed (off-chain) the request, so it must be an EOA...\\n payable(req.from).transfer(address(this).balance);\\n }\\n\\n return (success,ret);\\n }\\n\\n function _verifyNonce(ForwardRequest calldata req) internal view {\\n require(nonces[req.from] == req.nonce, \\\"FWD: nonce mismatch\\\");\\n }\\n\\n function _verifyAndUpdateNonce(ForwardRequest calldata req) internal {\\n require(nonces[req.from]++ == req.nonce, \\\"FWD: nonce mismatch\\\");\\n }\\n\\n /// @inheritdoc IForwarder\\n function registerRequestType(string calldata typeName, string calldata typeSuffix) external override {\\n\\n for (uint256 i = 0; i < bytes(typeName).length; i++) {\\n bytes1 c = bytes(typeName)[i];\\n require(c != \\\"(\\\" && c != \\\")\\\", \\\"FWD: invalid typename\\\");\\n }\\n\\n string memory requestType = string(abi.encodePacked(typeName, \\\"(\\\", GENERIC_PARAMS, \\\",\\\", typeSuffix));\\n registerRequestTypeInternal(requestType);\\n }\\n\\n /// @inheritdoc IForwarder\\n function registerDomainSeparator(string calldata name, string calldata version) external override {\\n uint256 chainId;\\n /* solhint-disable-next-line no-inline-assembly */\\n assembly { chainId := chainid() }\\n\\n bytes memory domainValue = abi.encode(\\n keccak256(bytes(EIP712_DOMAIN_TYPE)),\\n keccak256(bytes(name)),\\n keccak256(bytes(version)),\\n chainId,\\n address(this));\\n\\n bytes32 domainHash = keccak256(domainValue);\\n\\n domains[domainHash] = true;\\n emit DomainRegistered(domainHash, domainValue);\\n }\\n\\n function registerRequestTypeInternal(string memory requestType) internal {\\n\\n bytes32 requestTypehash = keccak256(bytes(requestType));\\n typeHashes[requestTypehash] = true;\\n emit RequestTypeRegistered(requestTypehash, requestType);\\n }\\n\\n function _verifySig(\\n ForwardRequest calldata req,\\n bytes32 domainSeparator,\\n bytes32 requestTypeHash,\\n bytes calldata suffixData,\\n bytes calldata sig)\\n internal\\n virtual\\n view\\n {\\n require(domains[domainSeparator], \\\"FWD: unregistered domain sep.\\\");\\n require(typeHashes[requestTypeHash], \\\"FWD: unregistered typehash\\\");\\n bytes32 digest = keccak256(abi.encodePacked(\\n \\\"\\\\x19\\\\x01\\\", domainSeparator,\\n keccak256(_getEncoded(req, requestTypeHash, suffixData))\\n ));\\n // solhint-disable-next-line avoid-tx-origin\\n require(tx.origin == DRY_RUN_ADDRESS || digest.recover(sig) == req.from, \\\"FWD: signature mismatch\\\");\\n }\\n\\n /**\\n * @notice Creates a byte array that is a valid ABI encoding of a request of a `RequestType` type. See `execute()`.\\n */\\n function _getEncoded(\\n ForwardRequest calldata req,\\n bytes32 requestTypeHash,\\n bytes calldata suffixData\\n )\\n public\\n pure\\n returns (\\n bytes memory\\n ) {\\n // we use encodePacked since we append suffixData as-is, not as dynamic param.\\n // still, we must make sure all first params are encoded as abi.encode()\\n // would encode them - as 256-bit-wide params.\\n return abi.encodePacked(\\n requestTypeHash,\\n uint256(uint160(req.from)),\\n uint256(uint160(req.to)),\\n req.value,\\n req.gas,\\n req.nonce,\\n keccak256(req.data),\\n req.validUntilTime,\\n suffixData\\n );\\n }\\n}\\n\",\"keccak256\":\"0x649ea2f205b514ccafbe0bd928e0cf309cde425dfd403a73b83e276309be651a\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/forwarder/IForwarder.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\n\\n/**\\n * @title The Forwarder Interface\\n * @notice The contracts implementing this interface take a role of authorization, authentication and replay protection\\n * for contracts that choose to trust a `Forwarder`, instead of relying on a mechanism built into the Ethereum protocol.\\n *\\n * @notice if the `Forwarder` contract decides that an incoming `ForwardRequest` is valid, it must append 20 bytes that\\n * represent the caller to the `data` field of the request and send this new data to the target address (the `to` field)\\n *\\n * :warning: **Warning** :warning: The Forwarder can have a full control over a `Recipient` contract.\\n * Any vulnerability in a `Forwarder` implementation can make all of its `Recipient` contracts susceptible!\\n * Recipient contracts should only trust forwarders that passed through security audit,\\n * otherwise they are susceptible to identity theft.\\n */\\ninterface IForwarder is IERC165 {\\n\\n /**\\n * @notice A representation of a request for a `Forwarder` to send `data` on behalf of a `from` to a target (`to`).\\n */\\n struct ForwardRequest {\\n address from;\\n address to;\\n uint256 value;\\n uint256 gas;\\n uint256 nonce;\\n bytes data;\\n uint256 validUntilTime;\\n }\\n\\n event DomainRegistered(bytes32 indexed domainSeparator, bytes domainValue);\\n\\n event RequestTypeRegistered(bytes32 indexed typeHash, string typeStr);\\n\\n /**\\n * @param from The address of a sender.\\n * @return The nonce for this address.\\n */\\n function getNonce(address from)\\n external view\\n returns(uint256);\\n\\n /**\\n * @notice Verify the transaction is valid and can be executed.\\n * Implementations must validate the signature and the nonce of the request are correct.\\n * Does not revert and returns successfully if the input is valid.\\n * Reverts if any validation has failed. For instance, if either signature or nonce are incorrect.\\n * Reverts if `domainSeparator` or `requestTypeHash` are not registered as well.\\n */\\n function verify(\\n ForwardRequest calldata forwardRequest,\\n bytes32 domainSeparator,\\n bytes32 requestTypeHash,\\n bytes calldata suffixData,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * @notice Executes a transaction specified by the `ForwardRequest`.\\n * The transaction is first verified and then executed.\\n * The success flag and returned bytes array of the `CALL` are returned as-is.\\n *\\n * This method would revert only in case of a verification error.\\n *\\n * All the target errors are reported using the returned success flag and returned bytes array.\\n *\\n * @param forwardRequest All requested transaction parameters.\\n * @param domainSeparator The domain used when signing this request.\\n * @param requestTypeHash The request type used when signing this request.\\n * @param suffixData The ABI-encoded extension data for the current `RequestType` used when signing this request.\\n * @param signature The client signature to be validated.\\n *\\n * @return success The success flag of the underlying `CALL` to the target address.\\n * @return ret The byte array returned by the underlying `CALL` to the target address.\\n */\\n function execute(\\n ForwardRequest calldata forwardRequest,\\n bytes32 domainSeparator,\\n bytes32 requestTypeHash,\\n bytes calldata suffixData,\\n bytes calldata signature\\n )\\n external payable\\n returns (bool success, bytes memory ret);\\n\\n /**\\n * @notice Register a new Request typehash.\\n *\\n * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\\n *\\n * @param typeName The name of the request type.\\n * @param typeSuffix Any extra data after the generic params. Must contain add at least one param.\\n * The generic ForwardRequest type is always registered by the constructor.\\n */\\n function registerRequestType(string calldata typeName, string calldata typeSuffix) external;\\n\\n /**\\n * @notice Register a new domain separator.\\n *\\n * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\\n *\\n * @notice The domain separator must have the following fields: `name`, `version`, `chainId`, `verifyingContract`.\\n * The `chainId` is the current network's `chainId`, and the `verifyingContract` is this Forwarder's address.\\n * This method accepts the domain name and version to create and register the domain separator value.\\n * @param name The domain's display name.\\n * @param version The domain/protocol version.\\n */\\n function registerDomainSeparator(string calldata name, string calldata version) external;\\n}\\n\",\"keccak256\":\"0x28669953bd3dcc98a5f959fa3cac97444584b6fbe59341681b9a59f11a83b171\",\"license\":\"GPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\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 if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(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; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // 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 require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\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 + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.4.22 <0.9.0;\\n\\nlibrary console {\\n address constant CONSOLE_ADDRESS =\\n 0x000000000000000000636F6e736F6c652e6c6f67;\\n\\n function _sendLogPayloadImplementation(bytes memory payload) internal view {\\n address consoleAddress = CONSOLE_ADDRESS;\\n /// @solidity memory-safe-assembly\\n assembly {\\n pop(\\n staticcall(\\n gas(),\\n consoleAddress,\\n add(payload, 32),\\n mload(payload),\\n 0,\\n 0\\n )\\n )\\n }\\n }\\n\\n function _castToPure(\\n function(bytes memory) internal view fnIn\\n ) internal pure returns (function(bytes memory) pure fnOut) {\\n assembly {\\n fnOut := fnIn\\n }\\n }\\n\\n function _sendLogPayload(bytes memory payload) internal pure {\\n _castToPure(_sendLogPayloadImplementation)(payload);\\n }\\n\\n function log() internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n }\\n function logInt(int256 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n }\\n\\n function logUint(uint256 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n }\\n\\n function logString(string memory p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n }\\n\\n function logBool(bool p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n }\\n\\n function logAddress(address p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n }\\n\\n function logBytes(bytes memory p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n }\\n\\n function logBytes1(bytes1 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n }\\n\\n function logBytes2(bytes2 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n }\\n\\n function logBytes3(bytes3 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n }\\n\\n function logBytes4(bytes4 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n }\\n\\n function logBytes5(bytes5 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n }\\n\\n function logBytes6(bytes6 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n }\\n\\n function logBytes7(bytes7 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n }\\n\\n function logBytes8(bytes8 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n }\\n\\n function logBytes9(bytes9 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n }\\n\\n function logBytes10(bytes10 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n }\\n\\n function logBytes11(bytes11 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n }\\n\\n function logBytes12(bytes12 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n }\\n\\n function logBytes13(bytes13 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n }\\n\\n function logBytes14(bytes14 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n }\\n\\n function logBytes15(bytes15 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n }\\n\\n function logBytes16(bytes16 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n }\\n\\n function logBytes17(bytes17 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n }\\n\\n function logBytes18(bytes18 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n }\\n\\n function logBytes19(bytes19 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n }\\n\\n function logBytes20(bytes20 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n }\\n\\n function logBytes21(bytes21 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n }\\n\\n function logBytes22(bytes22 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n }\\n\\n function logBytes23(bytes23 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n }\\n\\n function logBytes24(bytes24 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n }\\n\\n function logBytes25(bytes25 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n }\\n\\n function logBytes26(bytes26 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n }\\n\\n function logBytes27(bytes27 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n }\\n\\n function logBytes28(bytes28 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n }\\n\\n function logBytes29(bytes29 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n }\\n\\n function logBytes30(bytes30 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n }\\n\\n function logBytes31(bytes31 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n }\\n\\n function logBytes32(bytes32 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n }\\n\\n function log(uint256 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n }\\n\\n function log(string memory p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n }\\n\\n function log(bool p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n }\\n\\n function log(address p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n }\\n\\n function log(uint256 p0, uint256 p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n }\\n\\n function log(uint256 p0, string memory p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n }\\n\\n function log(uint256 p0, bool p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n }\\n\\n function log(uint256 p0, address p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n }\\n\\n function log(string memory p0, uint256 p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n }\\n\\n function log(string memory p0, string memory p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n }\\n\\n function log(string memory p0, bool p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n }\\n\\n function log(string memory p0, address p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n }\\n\\n function log(bool p0, uint256 p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n }\\n\\n function log(bool p0, string memory p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n }\\n\\n function log(bool p0, bool p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n }\\n\\n function log(bool p0, address p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n }\\n\\n function log(address p0, uint256 p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n }\\n\\n function log(address p0, string memory p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n }\\n\\n function log(address p0, bool p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n }\\n\\n function log(address p0, address p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, bool p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, address p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, address p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, string memory p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, bool p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, bool p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, address p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, address p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, address p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, uint256 p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, string memory p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, string memory p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, bool p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, bool p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, bool p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, address p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, address p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, address p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, address p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, uint256 p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, uint256 p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, string memory p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, string memory p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, string memory p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, bool p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, bool p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, bool p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, bool p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, address p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, address p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, address p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, address p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n}\\n\",\"keccak256\":\"0x7434453e6d3b7d0e5d0eb7846ffdbc27f0ccf3b163591263739b628074dc103a\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b5060006040518060a00160405280606181526020016200159660619139604051602001620000409190620000c8565b60408051601f1981840301815291905290506200005d8162000064565b5062000174565b8051602080830191909120600081815291829052604091829020805460ff19166001179055905181907f64d6bce64323458c44643c51fe45113efc882082f7b7fd5f09f0d69d2eedb20290620000bc9085906200010c565b60405180910390a25050565b6e08cdee4eec2e4c8a4cae2eacae6e85608b1b815260008251620000f481600f85016020870162000141565b602960f81b600f939091019283015250601001919050565b60208152600082518060208401526200012d81604085016020870162000141565b601f01601f19169190910160400192915050565b60005b838110156200015e57818101518382015260200162000144565b838111156200016e576000848401525b50505050565b61141280620001846000396000f3fe6080604052600436106100a05760003560e01c8063ad9f99c711610064578063ad9f99c714610199578063c3f28abd146101b9578063c722f177146101ce578063d9210be5146101fe578063e024dc7f1461021e578063e2b62f2d1461023f57600080fd5b806301ffc9a7146100ac578063066a310c146100e157806321fe98df146101035780632d0335ab146101335780639c7b45921461017757600080fd5b366100a757005b600080fd5b3480156100b857600080fd5b506100cc6100c7366004610eeb565b61025f565b60405190151581526020015b60405180910390f35b3480156100ed57600080fd5b506100f6610296565b6040516100d891906111c5565b34801561010f57600080fd5b506100cc61011e366004610ed2565b60006020819052908152604090205460ff1681565b34801561013f57600080fd5b5061016961014e366004610ea2565b6001600160a01b031660009081526002602052604090205490565b6040519081526020016100d8565b34801561018357600080fd5b50610197610192366004610f15565b6102b2565b005b3480156101a557600080fd5b506101976101b4366004610f81565b6103a9565b3480156101c557600080fd5b506100f66103ca565b3480156101da57600080fd5b506100cc6101e9366004610ed2565b60016020526000908152604090205460ff1681565b34801561020a57600080fd5b50610197610219366004610f15565b6103e6565b61023161022c366004610f81565b6104e9565b6040516100d89291906111a2565b34801561024b57600080fd5b506100f661025a366004611029565b610747565b60006001600160e01b031982166309788f9960e21b148061029057506301ffc9a760e01b6001600160e01b03198316145b92915050565b6040518060a001604052806061815260200161132a6061913981565b6000469050600060405180608001604052806052815260200161138b605291398051906020012086866040516102e99291906110fe565b604051809103902085856040516103019291906110fe565b6040805191829003822060208301949094528101919091526060810191909152608081018390523060a082015260c00160408051601f198184030181528282528051602080830191909120600081815260019283905293909320805460ff1916909117905592509081907f4bc68689cbe89a4a6333a3ab0a70093874da3e5bfb71e93102027f3f073687d8906103989085906111c5565b60405180910390a250505050505050565b6103b2876107e1565b6103c18787878787878761085e565b50505050505050565b60405180608001604052806052815260200161138b6052913981565b60005b8381101561049457600085858381811061040557610405611313565b909101356001600160f81b031916915050600560fb1b81148015906104385750602960f81b6001600160f81b0319821614155b6104815760405162461bcd60e51b81526020600482015260156024820152744657443a20696e76616c696420747970656e616d6560581b60448201526064015b60405180910390fd5b508061048c816112cc565b9150506103e9565b50600084846040518060a001604052806061815260200161132a6061913985856040516020016104c8959493929190611150565b60405160208183030381529060405290506104e281610a30565b5050505050565b600060606104fc8989898989898961085e565b61050589610a92565b60c089013515806105195750428960c00135115b61055c5760405162461bcd60e51b81526020600482015260146024820152731195d10e881c995c5d595cdd08195e1c1a5c995960621b6044820152606401610478565b600060408a01351561056d5750619c405b600061057c60a08c018c6111fc565b61058960208e018e610ea2565b60405160200161059b9392919061110e565b60408051601f1981840301815291905290506105bb8260608d0135611243565b60405a6105c990603f61127d565b6105d3919061125b565b10156106195760405162461bcd60e51b81526020600482015260156024820152744657443a20696e73756666696369656e742067617360581b6044820152606401610478565b61062960408c0160208d01610ea2565b6001600160a01b03168b606001358c604001358360405161064a9190611134565b600060405180830381858888f193505050503d8060008114610688576040519150601f19603f3d011682016040523d82523d6000602084013e61068d565b606091505b506040805180820190915260208082527f6578656375746520726573756c743a20737563636573733a202573207265743a9082015291955093506106d19085610b16565b6106da83610b5f565b60408b0135158015906106ed5750600047115b15610739576106ff60208c018c610ea2565b6001600160a01b03166108fc479081150290604051600060405180830381858888f19350505050158015610737573d6000803e3d6000fd5b505b505097509795505050505050565b6060836107576020870187610ea2565b6001600160a01b03166107706040880160208901610ea2565b6001600160a01b03166040880135606089013560808a013561079560a08c018c6111fc565b6040516107a39291906110fe565b6040519081900381206107c89796959493929160c08e0135908c908c906020016110ac565b6040516020818303038152906040529050949350505050565b6080810135600260006107f76020850185610ea2565b6001600160a01b03166001600160a01b03168152602001908152602001600020541461085b5760405162461bcd60e51b815260206004820152601360248201527208cae887440dcdedcc6ca40dad2e6dac2e8c6d606b1b6044820152606401610478565b50565b60008681526001602052604090205460ff166108bc5760405162461bcd60e51b815260206004820152601d60248201527f4657443a20756e7265676973746572656420646f6d61696e207365702e0000006044820152606401610478565b60008581526020819052604090205460ff1661091a5760405162461bcd60e51b815260206004820152601a60248201527f4657443a20756e726567697374657265642074797065686173680000000000006044820152606401610478565b60008661092989888888610747565b805160209182012060405161095593920161190160f01b81526002810192909252602282015260420190565b60408051601f19818403018152919052805160209091012090503215806109da57506109846020890189610ea2565b6001600160a01b03166109cf84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508693925050610ba29050565b6001600160a01b0316145b610a265760405162461bcd60e51b815260206004820152601760248201527f4657443a207369676e6174757265206d69736d617463680000000000000000006044820152606401610478565b5050505050505050565b8051602080830191909120600081815291829052604091829020805460ff19166001179055905181907f64d6bce64323458c44643c51fe45113efc882082f7b7fd5f09f0d69d2eedb20290610a869085906111c5565b60405180910390a25050565b608081013560026000610aa86020850185610ea2565b6001600160a01b0316815260208101919091526040016000908120805491610acf836112cc565b919050551461085b5760405162461bcd60e51b815260206004820152601360248201527208cae887440dcdedcc6ca40dad2e6dac2e8c6d606b1b6044820152606401610478565b610b5b8282604051602401610b2c9291906111d8565b60408051601f198184030181529190526020810180516001600160e01b031663c3b5563560e01b179052610bc6565b5050565b61085b81604051602401610b7391906111c5565b60408051601f198184030181529190526020810180516001600160e01b03166305f3bfab60e11b179052610bc6565b6000806000610bb18585610bcf565b91509150610bbe81610c15565b509392505050565b61085b81610d63565b600080825160411415610c065760208301516040840151606085015160001a610bfa87828585610d84565b94509450505050610c0e565b506000905060025b9250929050565b6000816004811115610c2957610c296112fd565b1415610c325750565b6001816004811115610c4657610c466112fd565b1415610c945760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610478565b6002816004811115610ca857610ca86112fd565b1415610cf65760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610478565b6003816004811115610d0a57610d0a6112fd565b141561085b5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610478565b60006a636f6e736f6c652e6c6f679050600080835160208501845afa505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610dbb5750600090506003610e3f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610e0f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e3857600060019250925050610e3f565b9150600090505b94509492505050565b60008083601f840112610e5a57600080fd5b50813567ffffffffffffffff811115610e7257600080fd5b602083019150836020828501011115610c0e57600080fd5b600060e08284031215610e9c57600080fd5b50919050565b600060208284031215610eb457600080fd5b81356001600160a01b0381168114610ecb57600080fd5b9392505050565b600060208284031215610ee457600080fd5b5035919050565b600060208284031215610efd57600080fd5b81356001600160e01b031981168114610ecb57600080fd5b60008060008060408587031215610f2b57600080fd5b843567ffffffffffffffff80821115610f4357600080fd5b610f4f88838901610e48565b90965094506020870135915080821115610f6857600080fd5b50610f7587828801610e48565b95989497509550505050565b600080600080600080600060a0888a031215610f9c57600080fd5b873567ffffffffffffffff80821115610fb457600080fd5b610fc08b838c01610e8a565b985060208a0135975060408a0135965060608a0135915080821115610fe457600080fd5b610ff08b838c01610e48565b909650945060808a013591508082111561100957600080fd5b506110168a828b01610e48565b989b979a50959850939692959293505050565b6000806000806060858703121561103f57600080fd5b843567ffffffffffffffff8082111561105757600080fd5b61106388838901610e8a565b9550602087013594506040870135915080821115610f6857600080fd5b6000815180845261109881602086016020860161129c565b601f01601f19169290920160200192915050565b8a81528960208201528860408201528760608201528660808201528560a08201528460c08201528360e082015260006101008385828501376000929093019092019081529a9950505050505050505050565b8183823760009101908152919050565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b6000825161114681846020870161129c565b9190910192915050565b84868237600085820160008152600560fb1b81528551611177816001840160208a0161129c565b600b60fa1b600192909101918201528385600283013760009301600201928352509095945050505050565b82151581526040602082015260006111bd6040830184611080565b949350505050565b602081526000610ecb6020830184611080565b6040815260006111eb6040830185611080565b905082151560208301529392505050565b6000808335601e1984360301811261121357600080fd5b83018035915067ffffffffffffffff82111561122e57600080fd5b602001915036819003821315610c0e57600080fd5b60008219821115611256576112566112e7565b500190565b60008261127857634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615611297576112976112e7565b500290565b60005b838110156112b757818101518382015260200161129f565b838111156112c6576000848401525b50505050565b60006000198214156112e0576112e06112e7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fdfe616464726573732066726f6d2c6164647265737320746f2c75696e743235362076616c75652c75696e74323536206761732c75696e74323536206e6f6e63652c627974657320646174612c75696e743235362076616c6964556e74696c54696d65454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429a2646970667358221220f85bbdae513994a0d6782b98ac9459a3fafc95625d8418bbf2eea1a38a7b088264736f6c63430008070033616464726573732066726f6d2c6164647265737320746f2c75696e743235362076616c75652c75696e74323536206761732c75696e74323536206e6f6e63652c627974657320646174612c75696e743235362076616c6964556e74696c54696d65", + "deployedBytecode": "0x6080604052600436106100a05760003560e01c8063ad9f99c711610064578063ad9f99c714610199578063c3f28abd146101b9578063c722f177146101ce578063d9210be5146101fe578063e024dc7f1461021e578063e2b62f2d1461023f57600080fd5b806301ffc9a7146100ac578063066a310c146100e157806321fe98df146101035780632d0335ab146101335780639c7b45921461017757600080fd5b366100a757005b600080fd5b3480156100b857600080fd5b506100cc6100c7366004610eeb565b61025f565b60405190151581526020015b60405180910390f35b3480156100ed57600080fd5b506100f6610296565b6040516100d891906111c5565b34801561010f57600080fd5b506100cc61011e366004610ed2565b60006020819052908152604090205460ff1681565b34801561013f57600080fd5b5061016961014e366004610ea2565b6001600160a01b031660009081526002602052604090205490565b6040519081526020016100d8565b34801561018357600080fd5b50610197610192366004610f15565b6102b2565b005b3480156101a557600080fd5b506101976101b4366004610f81565b6103a9565b3480156101c557600080fd5b506100f66103ca565b3480156101da57600080fd5b506100cc6101e9366004610ed2565b60016020526000908152604090205460ff1681565b34801561020a57600080fd5b50610197610219366004610f15565b6103e6565b61023161022c366004610f81565b6104e9565b6040516100d89291906111a2565b34801561024b57600080fd5b506100f661025a366004611029565b610747565b60006001600160e01b031982166309788f9960e21b148061029057506301ffc9a760e01b6001600160e01b03198316145b92915050565b6040518060a001604052806061815260200161132a6061913981565b6000469050600060405180608001604052806052815260200161138b605291398051906020012086866040516102e99291906110fe565b604051809103902085856040516103019291906110fe565b6040805191829003822060208301949094528101919091526060810191909152608081018390523060a082015260c00160408051601f198184030181528282528051602080830191909120600081815260019283905293909320805460ff1916909117905592509081907f4bc68689cbe89a4a6333a3ab0a70093874da3e5bfb71e93102027f3f073687d8906103989085906111c5565b60405180910390a250505050505050565b6103b2876107e1565b6103c18787878787878761085e565b50505050505050565b60405180608001604052806052815260200161138b6052913981565b60005b8381101561049457600085858381811061040557610405611313565b909101356001600160f81b031916915050600560fb1b81148015906104385750602960f81b6001600160f81b0319821614155b6104815760405162461bcd60e51b81526020600482015260156024820152744657443a20696e76616c696420747970656e616d6560581b60448201526064015b60405180910390fd5b508061048c816112cc565b9150506103e9565b50600084846040518060a001604052806061815260200161132a6061913985856040516020016104c8959493929190611150565b60405160208183030381529060405290506104e281610a30565b5050505050565b600060606104fc8989898989898961085e565b61050589610a92565b60c089013515806105195750428960c00135115b61055c5760405162461bcd60e51b81526020600482015260146024820152731195d10e881c995c5d595cdd08195e1c1a5c995960621b6044820152606401610478565b600060408a01351561056d5750619c405b600061057c60a08c018c6111fc565b61058960208e018e610ea2565b60405160200161059b9392919061110e565b60408051601f1981840301815291905290506105bb8260608d0135611243565b60405a6105c990603f61127d565b6105d3919061125b565b10156106195760405162461bcd60e51b81526020600482015260156024820152744657443a20696e73756666696369656e742067617360581b6044820152606401610478565b61062960408c0160208d01610ea2565b6001600160a01b03168b606001358c604001358360405161064a9190611134565b600060405180830381858888f193505050503d8060008114610688576040519150601f19603f3d011682016040523d82523d6000602084013e61068d565b606091505b506040805180820190915260208082527f6578656375746520726573756c743a20737563636573733a202573207265743a9082015291955093506106d19085610b16565b6106da83610b5f565b60408b0135158015906106ed5750600047115b15610739576106ff60208c018c610ea2565b6001600160a01b03166108fc479081150290604051600060405180830381858888f19350505050158015610737573d6000803e3d6000fd5b505b505097509795505050505050565b6060836107576020870187610ea2565b6001600160a01b03166107706040880160208901610ea2565b6001600160a01b03166040880135606089013560808a013561079560a08c018c6111fc565b6040516107a39291906110fe565b6040519081900381206107c89796959493929160c08e0135908c908c906020016110ac565b6040516020818303038152906040529050949350505050565b6080810135600260006107f76020850185610ea2565b6001600160a01b03166001600160a01b03168152602001908152602001600020541461085b5760405162461bcd60e51b815260206004820152601360248201527208cae887440dcdedcc6ca40dad2e6dac2e8c6d606b1b6044820152606401610478565b50565b60008681526001602052604090205460ff166108bc5760405162461bcd60e51b815260206004820152601d60248201527f4657443a20756e7265676973746572656420646f6d61696e207365702e0000006044820152606401610478565b60008581526020819052604090205460ff1661091a5760405162461bcd60e51b815260206004820152601a60248201527f4657443a20756e726567697374657265642074797065686173680000000000006044820152606401610478565b60008661092989888888610747565b805160209182012060405161095593920161190160f01b81526002810192909252602282015260420190565b60408051601f19818403018152919052805160209091012090503215806109da57506109846020890189610ea2565b6001600160a01b03166109cf84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508693925050610ba29050565b6001600160a01b0316145b610a265760405162461bcd60e51b815260206004820152601760248201527f4657443a207369676e6174757265206d69736d617463680000000000000000006044820152606401610478565b5050505050505050565b8051602080830191909120600081815291829052604091829020805460ff19166001179055905181907f64d6bce64323458c44643c51fe45113efc882082f7b7fd5f09f0d69d2eedb20290610a869085906111c5565b60405180910390a25050565b608081013560026000610aa86020850185610ea2565b6001600160a01b0316815260208101919091526040016000908120805491610acf836112cc565b919050551461085b5760405162461bcd60e51b815260206004820152601360248201527208cae887440dcdedcc6ca40dad2e6dac2e8c6d606b1b6044820152606401610478565b610b5b8282604051602401610b2c9291906111d8565b60408051601f198184030181529190526020810180516001600160e01b031663c3b5563560e01b179052610bc6565b5050565b61085b81604051602401610b7391906111c5565b60408051601f198184030181529190526020810180516001600160e01b03166305f3bfab60e11b179052610bc6565b6000806000610bb18585610bcf565b91509150610bbe81610c15565b509392505050565b61085b81610d63565b600080825160411415610c065760208301516040840151606085015160001a610bfa87828585610d84565b94509450505050610c0e565b506000905060025b9250929050565b6000816004811115610c2957610c296112fd565b1415610c325750565b6001816004811115610c4657610c466112fd565b1415610c945760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610478565b6002816004811115610ca857610ca86112fd565b1415610cf65760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610478565b6003816004811115610d0a57610d0a6112fd565b141561085b5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610478565b60006a636f6e736f6c652e6c6f679050600080835160208501845afa505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610dbb5750600090506003610e3f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610e0f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610e3857600060019250925050610e3f565b9150600090505b94509492505050565b60008083601f840112610e5a57600080fd5b50813567ffffffffffffffff811115610e7257600080fd5b602083019150836020828501011115610c0e57600080fd5b600060e08284031215610e9c57600080fd5b50919050565b600060208284031215610eb457600080fd5b81356001600160a01b0381168114610ecb57600080fd5b9392505050565b600060208284031215610ee457600080fd5b5035919050565b600060208284031215610efd57600080fd5b81356001600160e01b031981168114610ecb57600080fd5b60008060008060408587031215610f2b57600080fd5b843567ffffffffffffffff80821115610f4357600080fd5b610f4f88838901610e48565b90965094506020870135915080821115610f6857600080fd5b50610f7587828801610e48565b95989497509550505050565b600080600080600080600060a0888a031215610f9c57600080fd5b873567ffffffffffffffff80821115610fb457600080fd5b610fc08b838c01610e8a565b985060208a0135975060408a0135965060608a0135915080821115610fe457600080fd5b610ff08b838c01610e48565b909650945060808a013591508082111561100957600080fd5b506110168a828b01610e48565b989b979a50959850939692959293505050565b6000806000806060858703121561103f57600080fd5b843567ffffffffffffffff8082111561105757600080fd5b61106388838901610e8a565b9550602087013594506040870135915080821115610f6857600080fd5b6000815180845261109881602086016020860161129c565b601f01601f19169290920160200192915050565b8a81528960208201528860408201528760608201528660808201528560a08201528460c08201528360e082015260006101008385828501376000929093019092019081529a9950505050505050505050565b8183823760009101908152919050565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b6000825161114681846020870161129c565b9190910192915050565b84868237600085820160008152600560fb1b81528551611177816001840160208a0161129c565b600b60fa1b600192909101918201528385600283013760009301600201928352509095945050505050565b82151581526040602082015260006111bd6040830184611080565b949350505050565b602081526000610ecb6020830184611080565b6040815260006111eb6040830185611080565b905082151560208301529392505050565b6000808335601e1984360301811261121357600080fd5b83018035915067ffffffffffffffff82111561122e57600080fd5b602001915036819003821315610c0e57600080fd5b60008219821115611256576112566112e7565b500190565b60008261127857634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615611297576112976112e7565b500290565b60005b838110156112b757818101518382015260200161129f565b838111156112c6576000848401525b50505050565b60006000198214156112e0576112e06112e7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fdfe616464726573732066726f6d2c6164647265737320746f2c75696e743235362076616c75652c75696e74323536206761732c75696e74323536206e6f6e63652c627974657320646174612c75696e743235362076616c6964556e74696c54696d65454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429a2646970667358221220f85bbdae513994a0d6782b98ac9459a3fafc95625d8418bbf2eea1a38a7b088264736f6c63430008070033", + "devdoc": { + "kind": "dev", + "methods": { + "execute((address,address,uint256,uint256,uint256,bytes,uint256),bytes32,bytes32,bytes,bytes)": { + "params": { + "domainSeparator": "The domain used when signing this request.", + "forwardRequest": "All requested transaction parameters.", + "requestTypeHash": "The request type used when signing this request.", + "signature": "The client signature to be validated.", + "suffixData": "The ABI-encoded extension data for the current `RequestType` used when signing this request." + }, + "returns": { + "ret": "The byte array returned by the underlying `CALL` to the target address.", + "success": "The success flag of the underlying `CALL` to the target address." + } + }, + "getNonce(address)": { + "params": { + "from": "The address of a sender." + }, + "returns": { + "_0": "The nonce for this address." + } + }, + "registerDomainSeparator(string,string)": { + "params": { + "name": "The domain's display name.", + "version": "The domain/protocol version." + } + }, + "registerRequestType(string,string)": { + "params": { + "typeName": "The name of the request type.", + "typeSuffix": "Any extra data after the generic params. Must contain add at least one param. The generic ForwardRequest type is always registered by the constructor." + } + }, + "supportsInterface(bytes4)": { + "details": "Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas." + } + }, + "title": "The Forwarder Implementation", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "_getEncoded((address,address,uint256,uint256,uint256,bytes,uint256),bytes32,bytes)": { + "notice": "Creates a byte array that is a valid ABI encoding of a request of a `RequestType` type. See `execute()`." + }, + "execute((address,address,uint256,uint256,uint256,bytes,uint256),bytes32,bytes32,bytes,bytes)": { + "notice": "Executes a transaction specified by the `ForwardRequest`. The transaction is first verified and then executed. The success flag and returned bytes array of the `CALL` are returned as-is. This method would revert only in case of a verification error. All the target errors are reported using the returned success flag and returned bytes array." + }, + "registerDomainSeparator(string,string)": { + "notice": "Register a new domain separator.This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.The domain separator must have the following fields: `name`, `version`, `chainId`, `verifyingContract`. The `chainId` is the current network's `chainId`, and the `verifyingContract` is this Forwarder's address. This method accepts the domain name and version to create and register the domain separator value." + }, + "registerRequestType(string,string)": { + "notice": "Register a new Request typehash.This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712." + }, + "verify((address,address,uint256,uint256,uint256,bytes,uint256),bytes32,bytes32,bytes,bytes)": { + "notice": "Verify the transaction is valid and can be executed. Implementations must validate the signature and the nonce of the request are correct. Does not revert and returns successfully if the input is valid. Reverts if any validation has failed. For instance, if either signature or nonce are incorrect. Reverts if `domainSeparator` or `requestTypeHash` are not registered as well." + } + }, + "notice": "This implementation of the `IForwarder` interface uses ERC-712 signatures and stored nonces for verification.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4325, + "contract": "@opengsn/contracts/src/forwarder/Forwarder.sol:Forwarder", + "label": "typeHashes", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_bytes32,t_bool)" + }, + { + "astId": 4329, + "contract": "@opengsn/contracts/src/forwarder/Forwarder.sol:Forwarder", + "label": "domains", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_bool)" + }, + { + "astId": 4333, + "contract": "@opengsn/contracts/src/forwarder/Forwarder.sol:Forwarder", + "label": "nonces", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_uint256)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_bool)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/gsn/deploy/data/deployments/amoy/Penalizer.json b/gsn/deploy/data/deployments/amoy/Penalizer.json new file mode 100644 index 00000000..06abf6ea --- /dev/null +++ b/gsn/deploy/data/deployments/amoy/Penalizer.json @@ -0,0 +1,416 @@ +{ + "address": "0x6d57Dff87ED83c85Bcd79560AFc95004F398D6E2", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_penalizeBlockDelay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_penalizeBlockExpiration", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "commitHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "readyBlockNumber", + "type": "uint256" + } + ], + "name": "CommitAdded", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "commitHash", + "type": "bytes32" + } + ], + "name": "commit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "commits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "rawTransaction", + "type": "bytes" + } + ], + "name": "decodeTransaction", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IPenalizer.Transaction", + "name": "transaction", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getPenalizeBlockDelay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPenalizeBlockExpiration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "rawTransaction", + "type": "bytes" + } + ], + "name": "isTransactionTypeValid", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "unsignedTx", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "contract IRelayHub", + "name": "hub", + "type": "address" + }, + { + "internalType": "uint256", + "name": "randomValue", + "type": "uint256" + } + ], + "name": "penalizeIllegalTransaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "unsignedTx1", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature1", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "unsignedTx2", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature2", + "type": "bytes" + }, + { + "internalType": "contract IRelayHub", + "name": "hub", + "type": "address" + }, + { + "internalType": "uint256", + "name": "randomValue", + "type": "uint256" + } + ], + "name": "penalizeRepeatedNonce", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "versionPenalizer", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xab282b3bb7b7a6d4b7bf9ffca408c8053de01807401ba7f38e87e96fc91703b7", + "receipt": { + "to": null, + "from": "0x61B1E290d2F465d6667336d4934941aa2517AfA2", + "contractAddress": "0x6d57Dff87ED83c85Bcd79560AFc95004F398D6E2", + "transactionIndex": 0, + "gasUsed": "1685912", + "logsBloom": "0x00000000000000000008000000000000000000000000000000000000000000000000000000000002000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200008000000000000000000000000000020000000000000000000000000004000000000000000008001000000000000000000000000000000100000000000000000000000000000000000000800000000000000000000000000000000100000", + "blockHash": "0xf7e694602d02a5db34643ed74e28b449bf2d97fd16347e1268c18893aeac697e", + "transactionHash": "0xab282b3bb7b7a6d4b7bf9ffca408c8053de01807401ba7f38e87e96fc91703b7", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 4880201, + "transactionHash": "0xab282b3bb7b7a6d4b7bf9ffca408c8053de01807401ba7f38e87e96fc91703b7", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x00000000000000000000000061b1e290d2f465d6667336d4934941aa2517afa2", + "0x000000000000000000000000ac75d6efec891724b88b916b36e2ef38bcbec73f" + ], + "data": "0x00000000000000000000000000000000000000000000000001675fae8f7260180000000000000000000000000000000000000000000000000537b785fc4a8000000000000000000000000000000000000000000000000017467ec6e432168cf900000000000000000000000000000000000000000000000003d057d76cd81fe800000000000000000000000000000000000000000000001747e62692c188ed11", + "logIndex": 0, + "blockHash": "0xf7e694602d02a5db34643ed74e28b449bf2d97fd16347e1268c18893aeac697e" + } + ], + "blockNumber": 4880201, + "cumulativeGasUsed": "1685912", + "status": 1, + "byzantium": true + }, + "args": [ + 5, + 5 + ], + "numDeployments": 1, + "solcInputHash": "766eaa539015b343a6f8732a84d5a9ae", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_penalizeBlockDelay\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_penalizeBlockExpiration\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"commitHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"readyBlockNumber\",\"type\":\"uint256\"}],\"name\":\"CommitAdded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitHash\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"commits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"rawTransaction\",\"type\":\"bytes\"}],\"name\":\"decodeTransaction\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct IPenalizer.Transaction\",\"name\":\"transaction\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPenalizeBlockDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPenalizeBlockExpiration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"rawTransaction\",\"type\":\"bytes\"}],\"name\":\"isTransactionTypeValid\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"unsignedTx\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"},{\"internalType\":\"contract IRelayHub\",\"name\":\"hub\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"randomValue\",\"type\":\"uint256\"}],\"name\":\"penalizeIllegalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"unsignedTx1\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature1\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"unsignedTx2\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature2\",\"type\":\"bytes\"},{\"internalType\":\"contract IRelayHub\",\"name\":\"hub\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"randomValue\",\"type\":\"uint256\"}],\"name\":\"penalizeRepeatedNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"versionPenalizer\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"commit(bytes32)\":{\"params\":{\"commitHash\":\"The hash of the report of a penalizable behaviour the reporter wants to reveal. Calculated as `commit(keccak(encodedPenalizeFunction))`.\"}},\"decodeTransaction(bytes)\":{\"returns\":{\"transaction\":\"The details that the `Penalizer` needs to decide if the transaction is penalizable.\"}},\"getPenalizeBlockDelay()\":{\"returns\":{\"_0\":\"The minimum delay between commit and reveal steps.\"}},\"getPenalizeBlockExpiration()\":{\"returns\":{\"_0\":\"The maximum delay between commit and reveal steps.\"}},\"isTransactionTypeValid(bytes)\":{\"returns\":{\"_0\":\"`true` if raw transaction is of types Legacy, 1 or 2. `false` otherwise.\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"stateVariables\":{\"versionPenalizer\":{\"return\":\"a SemVer-compliant version of the `Penalizer` contract.\",\"returns\":{\"_0\":\"a SemVer-compliant version of the `Penalizer` contract.\"}}},\"title\":\"The Penalizer Implementation\",\"version\":1},\"userdoc\":{\"events\":{\"CommitAdded(address,bytes32,uint256)\":{\"notice\":\"Emitted once the reporter submits the first step in the commit-reveal process.\"}},\"kind\":\"user\",\"methods\":{\"commit(bytes32)\":{\"notice\":\"Called by the reporter as the first step in the commit-reveal process. Any sender can call it to make sure no-one can front-run it to claim this penalization.\"},\"penalizeIllegalTransaction(bytes,bytes,address,uint256)\":{\"notice\":\"Called by the reporter as the second step in the commit-reveal process. The Relay Workers are not allowed to make calls other than to the `relayCall` method.\"},\"penalizeRepeatedNonce(bytes,bytes,bytes,bytes,address,uint256)\":{\"notice\":\"Called by the reporter as the second step in the commit-reveal process. If a Relay Worker attacked the system by signing multiple transactions with same nonce so only one is accepted, anyone can grab both transactions from the blockchain and submit them here. Check whether `unsignedTx1` != `unsignedTx2`, that both are signed by the same address, and that `unsignedTx1.nonce` == `unsignedTx2.nonce`. If all conditions are met, relay is considered an \\\"offending relay\\\". The offending relay will be unregistered immediately, its stake will be forfeited and given to the address who reported it (the `msg.sender`), thus incentivizing anyone to report offending relays.\"}},\"notice\":\"This Penalizer supports parsing Legacy, Type 1 and Type 2 raw RLP Encoded transactions.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@opengsn/contracts/src/Penalizer.sol\":\"Penalizer\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@opengsn/contracts/src/Penalizer.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\n\\nimport \\\"./utils/RLPReader.sol\\\";\\nimport \\\"./utils/GsnUtils.sol\\\";\\nimport \\\"./interfaces/IRelayHub.sol\\\";\\nimport \\\"./interfaces/IPenalizer.sol\\\";\\n\\n/**\\n * @title The Penalizer Implementation\\n *\\n * @notice This Penalizer supports parsing Legacy, Type 1 and Type 2 raw RLP Encoded transactions.\\n */\\ncontract Penalizer is IPenalizer, ERC165 {\\n using ECDSA for bytes32;\\n\\n /// @inheritdoc IPenalizer\\n string public override versionPenalizer = \\\"3.0.0-beta.3+opengsn.penalizer.ipenalizer\\\";\\n\\n uint256 internal immutable penalizeBlockDelay;\\n uint256 internal immutable penalizeBlockExpiration;\\n\\n constructor(\\n uint256 _penalizeBlockDelay,\\n uint256 _penalizeBlockExpiration\\n ) {\\n penalizeBlockDelay = _penalizeBlockDelay;\\n penalizeBlockExpiration = _penalizeBlockExpiration;\\n }\\n\\n /// @inheritdoc IERC165\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\\n return interfaceId == type(IPenalizer).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /// @inheritdoc IPenalizer\\n function getPenalizeBlockDelay() external override view returns (uint256) {\\n return penalizeBlockDelay;\\n }\\n\\n /// @inheritdoc IPenalizer\\n function getPenalizeBlockExpiration() external override view returns (uint256) {\\n return penalizeBlockExpiration;\\n }\\n\\n function isLegacyTransaction(bytes calldata rawTransaction) internal pure returns (bool) {\\n uint8 transactionTypeByte = uint8(rawTransaction[0]);\\n return (transactionTypeByte >= 0xc0 && transactionTypeByte <= 0xfe);\\n }\\n\\n function isTransactionType1(bytes calldata rawTransaction) internal pure returns (bool) {\\n return (uint8(rawTransaction[0]) == 1);\\n }\\n\\n function isTransactionType2(bytes calldata rawTransaction) internal pure returns (bool) {\\n return (uint8(rawTransaction[0]) == 2);\\n }\\n\\n /// @return `true` if raw transaction is of types Legacy, 1 or 2. `false` otherwise.\\n function isTransactionTypeValid(bytes calldata rawTransaction) public pure returns(bool) {\\n return isLegacyTransaction(rawTransaction) || isTransactionType1(rawTransaction) || isTransactionType2(rawTransaction);\\n }\\n\\n /// @return transaction The details that the `Penalizer` needs to decide if the transaction is penalizable.\\n function decodeTransaction(bytes calldata rawTransaction) public pure returns (Transaction memory transaction) {\\n if (isTransactionType1(rawTransaction)) {\\n (transaction.nonce,\\n transaction.gasLimit,\\n transaction.to,\\n transaction.value,\\n transaction.data) = RLPReader.decodeTransactionType1(rawTransaction);\\n } else if (isTransactionType2(rawTransaction)) {\\n (transaction.nonce,\\n transaction.gasLimit,\\n transaction.to,\\n transaction.value,\\n transaction.data) = RLPReader.decodeTransactionType2(rawTransaction);\\n } else {\\n (transaction.nonce,\\n transaction.gasLimit,\\n transaction.to,\\n transaction.value,\\n transaction.data) = RLPReader.decodeLegacyTransaction(rawTransaction);\\n }\\n return transaction;\\n }\\n\\n mapping(bytes32 => uint256) public commits;\\n\\n /// @inheritdoc IPenalizer\\n function commit(bytes32 commitHash) external override {\\n uint256 readyBlockNumber = block.number + penalizeBlockDelay;\\n commits[commitHash] = readyBlockNumber;\\n emit CommitAdded(msg.sender, commitHash, readyBlockNumber);\\n }\\n\\n /// Modifier that verifies there was a `commit` operation before this call that has not expired yet.\\n modifier commitRevealOnly() {\\n bytes32 commitHash = keccak256(abi.encodePacked(keccak256(msg.data), msg.sender));\\n uint256 readyBlockNumber = commits[commitHash];\\n delete commits[commitHash];\\n // msg.sender can only be fake during off-chain view call, allowing Penalizer process to check transactions\\n if(msg.sender != address(type(uint160).max)) {\\n require(readyBlockNumber != 0, \\\"no commit\\\");\\n require(readyBlockNumber < block.number, \\\"reveal penalize too soon\\\");\\n require(readyBlockNumber + penalizeBlockExpiration > block.number, \\\"reveal penalize too late\\\");\\n }\\n _;\\n }\\n\\n /// @inheritdoc IPenalizer\\n function penalizeRepeatedNonce(\\n bytes calldata unsignedTx1,\\n bytes calldata signature1,\\n bytes calldata unsignedTx2,\\n bytes calldata signature2,\\n IRelayHub hub,\\n uint256 randomValue\\n )\\n public\\n override\\n commitRevealOnly {\\n (randomValue);\\n _penalizeRepeatedNonce(unsignedTx1, signature1, unsignedTx2, signature2, hub);\\n }\\n\\n function _penalizeRepeatedNonce(\\n bytes calldata unsignedTx1,\\n bytes calldata signature1,\\n bytes calldata unsignedTx2,\\n bytes calldata signature2,\\n IRelayHub hub\\n )\\n private\\n {\\n address addr1 = keccak256(unsignedTx1).recover(signature1);\\n address addr2 = keccak256(unsignedTx2).recover(signature2);\\n\\n require(addr1 == addr2, \\\"Different signer\\\");\\n require(addr1 != address(0), \\\"ecrecover failed\\\");\\n\\n Transaction memory decodedTx1 = decodeTransaction(unsignedTx1);\\n Transaction memory decodedTx2 = decodeTransaction(unsignedTx2);\\n\\n // checking that the same nonce is used in both transaction, with both signed by the same address\\n // and the actual data is different\\n // note: we compare the hash of the tx to save gas over iterating both byte arrays\\n require(decodedTx1.nonce == decodedTx2.nonce, \\\"Different nonce\\\");\\n\\n bytes memory dataToCheck1 =\\n abi.encodePacked(decodedTx1.data, decodedTx1.gasLimit, decodedTx1.to, decodedTx1.value);\\n\\n bytes memory dataToCheck2 =\\n abi.encodePacked(decodedTx2.data, decodedTx2.gasLimit, decodedTx2.to, decodedTx2.value);\\n\\n require(keccak256(dataToCheck1) != keccak256(dataToCheck2), \\\"tx is equal\\\");\\n\\n penalize(addr1, hub);\\n }\\n\\n /// @inheritdoc IPenalizer\\n function penalizeIllegalTransaction(\\n bytes calldata unsignedTx,\\n bytes calldata signature,\\n IRelayHub hub,\\n uint256 randomValue\\n )\\n public\\n override\\n commitRevealOnly {\\n (randomValue);\\n _penalizeIllegalTransaction(unsignedTx, signature, hub);\\n }\\n\\n function _penalizeIllegalTransaction(\\n bytes calldata unsignedTx,\\n bytes calldata signature,\\n IRelayHub hub\\n )\\n private\\n {\\n if (isTransactionTypeValid(unsignedTx)) {\\n Transaction memory decodedTx = decodeTransaction(unsignedTx);\\n if (decodedTx.to == address(hub)) {\\n bytes4 selector = GsnUtils.getMethodSig(decodedTx.data);\\n bool isWrongMethodCall = selector != IRelayHub.relayCall.selector;\\n require(\\n isWrongMethodCall,\\n \\\"Legal relay transaction\\\");\\n }\\n }\\n address relay = keccak256(unsignedTx).recover(signature);\\n require(relay != address(0), \\\"ecrecover failed\\\");\\n penalize(relay, hub);\\n }\\n\\n function penalize(address relayWorker, IRelayHub hub) private {\\n hub.penalize(relayWorker, payable(msg.sender));\\n }\\n}\\n\",\"keccak256\":\"0x3e0cae81291ac5f282f2ae4deab0ad5bcc0e5c338188808566bfde607d89c148\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/forwarder/IForwarder.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\n\\n/**\\n * @title The Forwarder Interface\\n * @notice The contracts implementing this interface take a role of authorization, authentication and replay protection\\n * for contracts that choose to trust a `Forwarder`, instead of relying on a mechanism built into the Ethereum protocol.\\n *\\n * @notice if the `Forwarder` contract decides that an incoming `ForwardRequest` is valid, it must append 20 bytes that\\n * represent the caller to the `data` field of the request and send this new data to the target address (the `to` field)\\n *\\n * :warning: **Warning** :warning: The Forwarder can have a full control over a `Recipient` contract.\\n * Any vulnerability in a `Forwarder` implementation can make all of its `Recipient` contracts susceptible!\\n * Recipient contracts should only trust forwarders that passed through security audit,\\n * otherwise they are susceptible to identity theft.\\n */\\ninterface IForwarder is IERC165 {\\n\\n /**\\n * @notice A representation of a request for a `Forwarder` to send `data` on behalf of a `from` to a target (`to`).\\n */\\n struct ForwardRequest {\\n address from;\\n address to;\\n uint256 value;\\n uint256 gas;\\n uint256 nonce;\\n bytes data;\\n uint256 validUntilTime;\\n }\\n\\n event DomainRegistered(bytes32 indexed domainSeparator, bytes domainValue);\\n\\n event RequestTypeRegistered(bytes32 indexed typeHash, string typeStr);\\n\\n /**\\n * @param from The address of a sender.\\n * @return The nonce for this address.\\n */\\n function getNonce(address from)\\n external view\\n returns(uint256);\\n\\n /**\\n * @notice Verify the transaction is valid and can be executed.\\n * Implementations must validate the signature and the nonce of the request are correct.\\n * Does not revert and returns successfully if the input is valid.\\n * Reverts if any validation has failed. For instance, if either signature or nonce are incorrect.\\n * Reverts if `domainSeparator` or `requestTypeHash` are not registered as well.\\n */\\n function verify(\\n ForwardRequest calldata forwardRequest,\\n bytes32 domainSeparator,\\n bytes32 requestTypeHash,\\n bytes calldata suffixData,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * @notice Executes a transaction specified by the `ForwardRequest`.\\n * The transaction is first verified and then executed.\\n * The success flag and returned bytes array of the `CALL` are returned as-is.\\n *\\n * This method would revert only in case of a verification error.\\n *\\n * All the target errors are reported using the returned success flag and returned bytes array.\\n *\\n * @param forwardRequest All requested transaction parameters.\\n * @param domainSeparator The domain used when signing this request.\\n * @param requestTypeHash The request type used when signing this request.\\n * @param suffixData The ABI-encoded extension data for the current `RequestType` used when signing this request.\\n * @param signature The client signature to be validated.\\n *\\n * @return success The success flag of the underlying `CALL` to the target address.\\n * @return ret The byte array returned by the underlying `CALL` to the target address.\\n */\\n function execute(\\n ForwardRequest calldata forwardRequest,\\n bytes32 domainSeparator,\\n bytes32 requestTypeHash,\\n bytes calldata suffixData,\\n bytes calldata signature\\n )\\n external payable\\n returns (bool success, bytes memory ret);\\n\\n /**\\n * @notice Register a new Request typehash.\\n *\\n * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\\n *\\n * @param typeName The name of the request type.\\n * @param typeSuffix Any extra data after the generic params. Must contain add at least one param.\\n * The generic ForwardRequest type is always registered by the constructor.\\n */\\n function registerRequestType(string calldata typeName, string calldata typeSuffix) external;\\n\\n /**\\n * @notice Register a new domain separator.\\n *\\n * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\\n *\\n * @notice The domain separator must have the following fields: `name`, `version`, `chainId`, `verifyingContract`.\\n * The `chainId` is the current network's `chainId`, and the `verifyingContract` is this Forwarder's address.\\n * This method accepts the domain name and version to create and register the domain separator value.\\n * @param name The domain's display name.\\n * @param version The domain/protocol version.\\n */\\n function registerDomainSeparator(string calldata name, string calldata version) external;\\n}\\n\",\"keccak256\":\"0x28669953bd3dcc98a5f959fa3cac97444584b6fbe59341681b9a59f11a83b171\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/interfaces/IPenalizer.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\n\\nimport \\\"./IRelayHub.sol\\\";\\n\\n/**\\n * @title The Penalizer Interface\\n * @notice In some cases the behavior of a Relay Server may be found to be illegal.\\n * It is the responsibility of a `Penalizer` contract to judge whether there was a penalizable event.\\n *\\n * @notice In case there was, the `Penalizer` will direct the `RelayHub` to slash the stake of the faulty Relay Server.\\n */\\ninterface IPenalizer is IERC165 {\\n\\n /// @notice Emitted once the reporter submits the first step in the commit-reveal process.\\n event CommitAdded(address indexed sender, bytes32 indexed commitHash, uint256 readyBlockNumber);\\n\\n struct Transaction {\\n uint256 nonce;\\n uint256 gasLimit;\\n address to;\\n uint256 value;\\n bytes data;\\n }\\n\\n /**\\n * @notice Called by the reporter as the first step in the commit-reveal process.\\n * Any sender can call it to make sure no-one can front-run it to claim this penalization.\\n * @param commitHash The hash of the report of a penalizable behaviour the reporter wants to reveal.\\n * Calculated as `commit(keccak(encodedPenalizeFunction))`.\\n */\\n function commit(bytes32 commitHash) external;\\n\\n /**\\n * @notice Called by the reporter as the second step in the commit-reveal process.\\n * If a Relay Worker attacked the system by signing multiple transactions with same nonce so only one is accepted,\\n * anyone can grab both transactions from the blockchain and submit them here.\\n * Check whether `unsignedTx1` != `unsignedTx2`, that both are signed by the same address,\\n * and that `unsignedTx1.nonce` == `unsignedTx2.nonce`.\\n * If all conditions are met, relay is considered an \\\"offending relay\\\".\\n * The offending relay will be unregistered immediately, its stake will be forfeited and given\\n * to the address who reported it (the `msg.sender`), thus incentivizing anyone to report offending relays.\\n */\\n function penalizeRepeatedNonce(\\n bytes calldata unsignedTx1,\\n bytes calldata signature1,\\n bytes calldata unsignedTx2,\\n bytes calldata signature2,\\n IRelayHub hub,\\n uint256 randomValue\\n ) external;\\n\\n /**\\n * @notice Called by the reporter as the second step in the commit-reveal process.\\n * The Relay Workers are not allowed to make calls other than to the `relayCall` method.\\n */\\n function penalizeIllegalTransaction(\\n bytes calldata unsignedTx,\\n bytes calldata signature,\\n IRelayHub hub,\\n uint256 randomValue\\n ) external;\\n\\n /// @return a SemVer-compliant version of the `Penalizer` contract.\\n function versionPenalizer() external view returns (string memory);\\n\\n /// @return The minimum delay between commit and reveal steps.\\n function getPenalizeBlockDelay() external view returns (uint256);\\n\\n /// @return The maximum delay between commit and reveal steps.\\n function getPenalizeBlockExpiration() external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xafe97a535087b1a3a8d2170f675c673ba56d5c5b3dd9d9bdd5c66528cb653b3d\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/interfaces/IRelayHub.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\n\\nimport \\\"../utils/GsnTypes.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\n\\n/**\\n * @title The RelayHub interface\\n * @notice The implementation of this interface provides all the information the GSN client needs to\\n * create a valid `RelayRequest` and also serves as an entry point for such requests.\\n *\\n * @notice The RelayHub also handles all the related financial records and hold the balances of participants.\\n * The Paymasters keep their Ether deposited in the `RelayHub` in order to pay for the `RelayRequest`s that thay choose\\n * to pay for, and Relay Servers keep their earned Ether in the `RelayHub` until they choose to `withdraw()`\\n *\\n * @notice The RelayHub on each supported network only needs a single instance and there is usually no need for dApp\\n * developers or Relay Server operators to redeploy, reimplement, modify or override the `RelayHub`.\\n */\\ninterface IRelayHub is IERC165 {\\n /**\\n * @notice A struct that contains all the parameters of the `RelayHub` that can be modified after the deployment.\\n */\\n struct RelayHubConfig {\\n // maximum number of worker accounts allowed per manager\\n uint256 maxWorkerCount;\\n // Gas set aside for all relayCall() instructions to prevent unexpected out-of-gas exceptions\\n uint256 gasReserve;\\n // Gas overhead to calculate gasUseWithoutPost\\n uint256 postOverhead;\\n // Gas cost of all relayCall() instructions after actual 'calculateCharge()'\\n // Assume that relay has non-zero balance (costs 15'000 more otherwise).\\n uint256 gasOverhead;\\n // Minimum unstake delay seconds of a relay manager's stake on the StakeManager\\n uint256 minimumUnstakeDelay;\\n // Developers address\\n address devAddress;\\n // 0 < fee < 100, as percentage of total charge from paymaster to relayer\\n uint8 devFee;\\n // baseRelayFee The base fee the Relay Server charges for a single transaction in Ether, in wei.\\n uint80 baseRelayFee;\\n // pctRelayFee The percent of the total charge to add as a Relay Server fee to the total charge.\\n uint16 pctRelayFee;\\n }\\n\\n /// @notice Emitted when a configuration of the `RelayHub` is changed\\n event RelayHubConfigured(RelayHubConfig config);\\n\\n /// @notice Emitted when relays are added by a relayManager\\n event RelayWorkersAdded(\\n address indexed relayManager,\\n address[] newRelayWorkers,\\n uint256 workersCount\\n );\\n\\n /// @notice Emitted when an account withdraws funds from the `RelayHub`.\\n event Withdrawn(\\n address indexed account,\\n address indexed dest,\\n uint256 amount\\n );\\n\\n /// @notice Emitted when `depositFor` is called, including the amount and account that was funded.\\n event Deposited(\\n address indexed paymaster,\\n address indexed from,\\n uint256 amount\\n );\\n\\n /// @notice Emitted for each token configured for staking in setMinimumStakes\\n event StakingTokenDataChanged(\\n address token,\\n uint256 minimumStake\\n );\\n\\n /**\\n * @notice Emitted when an attempt to relay a call fails and the `Paymaster` does not accept the transaction.\\n * The actual relayed call was not executed, and the recipient not charged.\\n * @param reason contains a revert reason returned from preRelayedCall or forwarder.\\n */\\n event TransactionRejectedByPaymaster(\\n address indexed relayManager,\\n address indexed paymaster,\\n bytes32 indexed relayRequestID,\\n address from,\\n address to,\\n address relayWorker,\\n bytes4 selector,\\n uint256 innerGasUsed,\\n bytes reason\\n );\\n\\n /**\\n * @notice Emitted when a transaction is relayed. Note that the actual internal function call might be reverted.\\n * The reason for a revert will be indicated in the `status` field of a corresponding `RelayCallStatus` value.\\n * @notice `charge` is the Ether value deducted from the `Paymaster` balance.\\n * The amount added to the `relayManager` balance will be lower if there is an activated `devFee` in the `config`.\\n */\\n event TransactionRelayed(\\n address indexed relayManager,\\n address indexed relayWorker,\\n bytes32 indexed relayRequestID,\\n address from,\\n address to,\\n address paymaster,\\n bytes4 selector,\\n RelayCallStatus status,\\n uint256 charge\\n );\\n\\n /// @notice This event is emitted in case the internal function returns a value or reverts with a revert string.\\n event TransactionResult(\\n RelayCallStatus status,\\n bytes returnValue\\n );\\n\\n /// @notice This event is emitted in case this `RelayHub` is deprecated and will stop serving transactions soon.\\n event HubDeprecated(uint256 deprecationTime);\\n\\n /**\\n * @notice This event is emitted in case a `relayManager` has been deemed \\\"abandoned\\\" for being\\n * unresponsive for a prolonged period of time.\\n * @notice This event means the entire balance of the relay has been transferred to the `devAddress`.\\n */\\n event AbandonedRelayManagerBalanceEscheated(\\n address indexed relayManager,\\n uint256 balance\\n );\\n\\n /**\\n * Error codes that describe all possible failure reasons reported in the `TransactionRelayed` event `status` field.\\n * @param OK The transaction was successfully relayed and execution successful - never included in the event.\\n * @param RelayedCallFailed The transaction was relayed, but the relayed call failed.\\n * @param RejectedByPreRelayed The transaction was not relayed due to preRelatedCall reverting.\\n * @param RejectedByForwarder The transaction was not relayed due to forwarder check (signature,nonce).\\n * @param PostRelayedFailed The transaction was relayed and reverted due to postRelatedCall reverting.\\n * @param PaymasterBalanceChanged The transaction was relayed and reverted due to the paymaster balance change.\\n */\\n enum RelayCallStatus {\\n OK,\\n RelayedCallFailed,\\n RejectedByPreRelayed,\\n RejectedByForwarder,\\n RejectedByRecipientRevert,\\n PostRelayedFailed,\\n PaymasterBalanceChanged\\n }\\n\\n /**\\n * @notice Add new worker addresses controlled by the sender who must be a staked Relay Manager address.\\n * Emits a `RelayWorkersAdded` event.\\n * This function can be called multiple times, emitting new events.\\n */\\n function addRelayWorkers(address[] calldata newRelayWorkers) external;\\n\\n /**\\n * @notice The `RelayRegistrar` callback to notify the `RelayHub` that this `relayManager` has updated registration.\\n */\\n function onRelayServerRegistered(address relayManager) external;\\n\\n // Balance management\\n\\n /**\\n * @notice Deposits ether for a `Paymaster`, so that it can and pay for relayed transactions.\\n * :warning: **Warning** :warning: Unused balance can only be withdrawn by the holder itself, by calling `withdraw`.\\n * Emits a `Deposited` event.\\n */\\n function depositFor(address target) external payable;\\n\\n /**\\n * @notice Withdraws from an account's balance, sending it back to the caller.\\n * Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding.\\n * Emits a `Withdrawn` event.\\n */\\n function withdraw(address payable dest, uint256 amount) external;\\n\\n /**\\n * @notice Withdraws from an account's balance, sending funds to multiple provided addresses.\\n * Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding.\\n * Emits a `Withdrawn` event for each destination.\\n */\\n function withdrawMultiple(address payable[] memory dest, uint256[] memory amount) external;\\n\\n // Relaying\\n\\n\\n /**\\n * @notice Relays a transaction. For this to succeed, multiple conditions must be met:\\n * - `Paymaster`'s `preRelayCall` method must succeed and not revert.\\n * - the `msg.sender` must be a registered Relay Worker that the user signed to use.\\n * - the transaction's gas fees must be equal or larger than the ones that were signed by the sender.\\n * - the transaction must have enough gas to run all internal transactions if they use all gas available to them.\\n * - the `Paymaster` must have enough balance to pay the Relay Worker if all gas is spent.\\n *\\n * @notice If all conditions are met, the call will be relayed and the `Paymaster` charged.\\n *\\n * @param domainSeparatorName The name of the Domain Separator used to verify the EIP-712 signature\\n * @param maxAcceptanceBudget The maximum valid value for `paymaster.getGasLimits().acceptanceBudget` to return.\\n * @param relayRequest All details of the requested relayed call.\\n * @param signature The client's EIP-712 signature over the `relayRequest` struct.\\n * @param approvalData The dapp-specific data forwarded to the `Paymaster`'s `preRelayedCall` method.\\n * This value is **not** verified by the `RelayHub` in any way.\\n * As an example, it can be used to pass some kind of a third-party signature to the `Paymaster` for verification.\\n *\\n * Emits a `TransactionRelayed` event regardless of whether the transaction succeeded or failed.\\n */\\n function relayCall(\\n string calldata domainSeparatorName,\\n uint256 maxAcceptanceBudget,\\n GsnTypes.RelayRequest calldata relayRequest,\\n bytes calldata signature,\\n bytes calldata approvalData\\n )\\n external\\n returns (\\n bool paymasterAccepted,\\n uint256 charge,\\n IRelayHub.RelayCallStatus status,\\n bytes memory returnValue\\n );\\n\\n /**\\n * @notice In case the Relay Worker has been found to be in violation of some rules by the `Penalizer` contract,\\n * the `Penalizer` will call this method to execute a penalization.\\n * The `RelayHub` will look up the Relay Manager of the given Relay Worker and will forward the call to\\n * the `StakeManager` contract. The `RelayHub` does not perform the actual penalization either.\\n * @param relayWorker The address of the Relay Worker that committed a penalizable offense.\\n * @param beneficiary The address that called the `Penalizer` and will receive a reward for it.\\n */\\n function penalize(address relayWorker, address payable beneficiary) external;\\n\\n /**\\n * @notice Sets or changes the configuration of this `RelayHub`.\\n * @param _config The new configuration.\\n */\\n function setConfiguration(RelayHubConfig memory _config) external;\\n\\n /**\\n * @notice Sets or changes the minimum amount of a given `token` that needs to be staked so that the Relay Manager\\n * is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.\\n * @param token An array of addresses of ERC-20 compatible tokens.\\n * @param minimumStake An array of minimal amounts necessary for a corresponding token, in wei.\\n */\\n function setMinimumStakes(IERC20[] memory token, uint256[] memory minimumStake) external;\\n\\n /**\\n * @notice Deprecate hub by reverting all incoming `relayCall()` calls starting from a given timestamp\\n * @param _deprecationTime The timestamp in seconds after which the `RelayHub` stops serving transactions.\\n */\\n function deprecateHub(uint256 _deprecationTime) external;\\n\\n /**\\n * @notice\\n * @param relayManager\\n */\\n function escheatAbandonedRelayBalance(address relayManager) external;\\n\\n /**\\n * @notice The fee is expressed as a base fee in wei plus percentage of the actual charge.\\n * For example, a value '40' stands for a 40% fee, so the recipient will be charged for 1.4 times the spent amount.\\n * @param gasUsed An amount of gas used by the transaction.\\n * @param relayData The details of a transaction signed by the sender.\\n * @return The calculated charge, in wei.\\n */\\n function calculateCharge(uint256 gasUsed, GsnTypes.RelayData calldata relayData) external view returns (uint256);\\n\\n /**\\n * @notice The fee is expressed as a percentage of the actual charge.\\n * For example, a value '40' stands for a 40% fee, so the Relay Manager will only get 60% of the `charge`.\\n * @param charge The amount of Ether in wei the Paymaster will be charged for this transaction.\\n * @return The calculated devFee, in wei.\\n */\\n function calculateDevCharge(uint256 charge) external view returns (uint256);\\n /* getters */\\n\\n /// @return config The configuration of the `RelayHub`.\\n function getConfiguration() external view returns (RelayHubConfig memory config);\\n\\n /**\\n * @param token An address of an ERC-20 compatible tokens.\\n * @return The minimum amount of a given `token` that needs to be staked so that the Relay Manager\\n * is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.\\n */\\n function getMinimumStakePerToken(IERC20 token) external view returns (uint256);\\n\\n /**\\n * @param worker An address of the Relay Worker.\\n * @return The address of its Relay Manager.\\n */\\n function getWorkerManager(address worker) external view returns (address);\\n\\n /**\\n * @param manager An address of the Relay Manager.\\n * @return The count of Relay Workers associated with this Relay Manager.\\n */\\n function getWorkerCount(address manager) external view returns (uint256);\\n\\n /// @return An account's balance. It can be either a deposit of a `Paymaster`, or a revenue of a Relay Manager.\\n function balanceOf(address target) external view returns (uint256);\\n\\n /// @return The `StakeManager` address for this `RelayHub`.\\n function getStakeManager() external view returns (IStakeManager);\\n\\n /// @return The `Penalizer` address for this `RelayHub`.\\n function getPenalizer() external view returns (address);\\n\\n /// @return The `RelayRegistrar` address for this `RelayHub`.\\n function getRelayRegistrar() external view returns (address);\\n\\n /// @return The `BatchGateway` address for this `RelayHub`.\\n function getBatchGateway() external view returns (address);\\n\\n /**\\n * @notice Uses `StakeManager` to decide if the Relay Manager can be considered staked or not.\\n * Returns if the stake's token, amount and delay satisfy all requirements, reverts otherwise.\\n */\\n function verifyRelayManagerStaked(address relayManager) external view;\\n\\n /**\\n * @notice Uses `StakeManager` to check if the Relay Manager can be considered abandoned or not.\\n * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\\n */\\n function isRelayEscheatable(address relayManager) external view returns (bool);\\n\\n /// @return `true` if the `RelayHub` is deprecated, `false` it it is not deprecated and can serve transactions.\\n function isDeprecated() external view returns (bool);\\n\\n /// @return The timestamp from which the hub no longer allows relaying calls.\\n function getDeprecationTime() external view returns (uint256);\\n\\n /// @return The block number in which the contract has been deployed.\\n function getCreationBlock() external view returns (uint256);\\n\\n /// @return a SemVer-compliant version of the `RelayHub` contract.\\n function versionHub() external view returns (string memory);\\n\\n /// @return A total measurable amount of gas left to current execution. Same as 'gasleft()' for pure EVMs.\\n function aggregateGasleft() external view returns (uint256);\\n}\\n\\n\",\"keccak256\":\"0x0ab29ca5985c98f530e5985e3d9dd14f00d34527410ce980b51b26e57bb0121c\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @title The StakeManager Interface\\n * @notice In order to prevent an attacker from registering a large number of unresponsive relays, the GSN requires\\n * the Relay Server to maintain a permanently locked stake in the system before being able to register.\\n *\\n * @notice Also, in some cases the behavior of a Relay Server may be found to be illegal by a `Penalizer` contract.\\n * In such case, the stake will never be returned to the Relay Server operator and will be slashed.\\n *\\n * @notice An implementation of this interface is tasked with keeping Relay Servers' stakes, made in any ERC-20 token.\\n * Note that the `RelayHub` chooses which ERC-20 tokens to support and how much stake is needed.\\n */\\ninterface IStakeManager is IERC165 {\\n\\n /// @notice Emitted when a `stake` or `unstakeDelay` are initialized or increased.\\n event StakeAdded(\\n address indexed relayManager,\\n address indexed owner,\\n IERC20 token,\\n uint256 stake,\\n uint256 unstakeDelay\\n );\\n\\n /// @notice Emitted once a stake is scheduled for withdrawal.\\n event StakeUnlocked(\\n address indexed relayManager,\\n address indexed owner,\\n uint256 withdrawTime\\n );\\n\\n /// @notice Emitted when owner withdraws `relayManager` funds.\\n event StakeWithdrawn(\\n address indexed relayManager,\\n address indexed owner,\\n IERC20 token,\\n uint256 amount\\n );\\n\\n /// @notice Emitted when an authorized `RelayHub` penalizes a `relayManager`.\\n event StakePenalized(\\n address indexed relayManager,\\n address indexed beneficiary,\\n IERC20 token,\\n uint256 reward\\n );\\n\\n /// @notice Emitted when a `relayManager` adds a new `RelayHub` to a list of authorized.\\n event HubAuthorized(\\n address indexed relayManager,\\n address indexed relayHub\\n );\\n\\n /// @notice Emitted when a `relayManager` removes a `RelayHub` from a list of authorized.\\n event HubUnauthorized(\\n address indexed relayManager,\\n address indexed relayHub,\\n uint256 removalTime\\n );\\n\\n /// @notice Emitted when a `relayManager` sets its `owner`. This is necessary to prevent stake hijacking.\\n event OwnerSet(\\n address indexed relayManager,\\n address indexed owner\\n );\\n\\n /// @notice Emitted when a `burnAddress` is changed.\\n event BurnAddressSet(\\n address indexed burnAddress\\n );\\n\\n /// @notice Emitted when a `devAddress` is changed.\\n event DevAddressSet(\\n address indexed devAddress\\n );\\n\\n /// @notice Emitted if Relay Server is inactive for an `abandonmentDelay` and contract owner initiates its removal.\\n event RelayServerAbandoned(\\n address indexed relayManager,\\n uint256 abandonedTime\\n );\\n\\n /// @notice Emitted to indicate an action performed by a relay server to prevent it from being marked as abandoned.\\n event RelayServerKeepalive(\\n address indexed relayManager,\\n uint256 keepaliveTime\\n );\\n\\n /// @notice Emitted when the stake of an abandoned relayer has been confiscated and transferred to the `devAddress`.\\n event AbandonedRelayManagerStakeEscheated(\\n address indexed relayManager,\\n address indexed owner,\\n IERC20 token,\\n uint256 amount\\n );\\n\\n /**\\n * @param stake - amount of ether staked for this relay\\n * @param unstakeDelay - number of seconds to elapse before the owner can retrieve the stake after calling 'unlock'\\n * @param withdrawTime - timestamp in seconds when 'withdraw' will be callable, or zero if the unlock has not been called\\n * @param owner - address that receives revenue and manages relayManager's stake\\n */\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelay;\\n uint256 withdrawTime;\\n uint256 abandonedTime;\\n uint256 keepaliveTime;\\n IERC20 token;\\n address owner;\\n }\\n\\n struct RelayHubInfo {\\n uint256 removalTime;\\n }\\n\\n /**\\n * @param devAddress - the address that will receive the 'abandoned' stake\\n * @param abandonmentDelay - the amount of time after which the relay can be marked as 'abandoned'\\n * @param escheatmentDelay - the amount of time after which the abandoned relay's stake and balance may be withdrawn to the `devAddress`\\n */\\n struct AbandonedRelayServerConfig {\\n address devAddress;\\n uint256 abandonmentDelay;\\n uint256 escheatmentDelay;\\n }\\n\\n /**\\n * @notice Set the owner of a Relay Manager. Called only by the RelayManager itself.\\n * Note that owners cannot transfer ownership - if the entry already exists, reverts.\\n * @param owner - owner of the relay (as configured off-chain)\\n */\\n function setRelayManagerOwner(address owner) external;\\n\\n /**\\n * @notice Put a stake for a relayManager and set its unstake delay.\\n * Only the owner can call this function. If the entry does not exist, reverts.\\n * The owner must give allowance of the ERC-20 token to the StakeManager before calling this method.\\n * It is the RelayHub who has a configurable list of minimum stakes per token. StakeManager accepts all tokens.\\n * @param token The address of an ERC-20 token that is used by the relayManager as a stake\\n * @param relayManager The address that represents a stake entry and controls relay registrations on relay hubs\\n * @param unstakeDelay The number of seconds to elapse before an owner can retrieve the stake after calling `unlock`\\n * @param amount The amount of tokens to be taken from the relayOwner and locked in the StakeManager as a stake\\n */\\n function stakeForRelayManager(IERC20 token, address relayManager, uint256 unstakeDelay, uint256 amount) external;\\n\\n /**\\n * @notice Schedule the unlocking of the stake. The `unstakeDelay` must pass before owner can call `withdrawStake`.\\n * @param relayManager The address of a Relay Manager whose stake is to be unlocked.\\n */\\n function unlockStake(address relayManager) external;\\n /**\\n * @notice Withdraw the unlocked stake.\\n * @param relayManager The address of a Relay Manager whose stake is to be withdrawn.\\n */\\n function withdrawStake(address relayManager) external;\\n\\n /**\\n * @notice Add the `RelayHub` to a list of authorized by this Relay Manager.\\n * This allows the RelayHub to penalize this Relay Manager. The `RelayHub` cannot trust a Relay it cannot penalize.\\n * @param relayManager The address of a Relay Manager whose stake is to be authorized for the new `RelayHub`.\\n * @param relayHub The address of a `RelayHub` to be authorized.\\n */\\n function authorizeHubByOwner(address relayManager, address relayHub) external;\\n\\n /**\\n * @notice Same as `authorizeHubByOwner` but can be called by the RelayManager itself.\\n */\\n function authorizeHubByManager(address relayHub) external;\\n\\n /**\\n * @notice Remove the `RelayHub` from a list of authorized by this Relay Manager.\\n * @param relayManager The address of a Relay Manager.\\n * @param relayHub The address of a `RelayHub` to be unauthorized.\\n */\\n function unauthorizeHubByOwner(address relayManager, address relayHub) external;\\n\\n /**\\n * @notice Same as `unauthorizeHubByOwner` but can be called by the RelayManager itself.\\n */\\n function unauthorizeHubByManager(address relayHub) external;\\n\\n /**\\n * Slash the stake of the relay relayManager. In order to prevent stake kidnapping, burns part of stake on the way.\\n * @param relayManager The address of a Relay Manager to be penalized.\\n * @param beneficiary The address that receives part of the penalty amount.\\n * @param amount A total amount of penalty to be withdrawn from stake.\\n */\\n function penalizeRelayManager(address relayManager, address beneficiary, uint256 amount) external;\\n\\n /**\\n * @notice Allows the contract owner to set the given `relayManager` as abandoned after a configurable delay.\\n * Its entire stake and balance will be taken from a relay if it does not respond to being marked as abandoned.\\n */\\n function markRelayAbandoned(address relayManager) external;\\n\\n /**\\n * @notice If more than `abandonmentDelay` has passed since the last Keepalive transaction, and relay manager\\n * has been marked as abandoned, and after that more that `escheatmentDelay` have passed, entire stake and\\n * balance will be taken from this relay.\\n */\\n function escheatAbandonedRelayStake(address relayManager) external;\\n\\n /**\\n * @notice Sets a new `keepaliveTime` for the given `relayManager`, preventing it from being marked as abandoned.\\n * Can be called by an authorized `RelayHub` or by the `relayOwner` address.\\n */\\n function updateRelayKeepaliveTime(address relayManager) external;\\n\\n /**\\n * @notice Check if the Relay Manager can be considered abandoned or not.\\n * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\\n */\\n function isRelayEscheatable(address relayManager) external view returns(bool);\\n\\n /**\\n * @notice Get the stake details information for the given Relay Manager.\\n * @param relayManager The address of a Relay Manager.\\n * @return stakeInfo The `StakeInfo` structure.\\n * @return isSenderAuthorizedHub `true` if the `msg.sender` for this call was a `RelayHub` that is authorized now.\\n * `false` if the `msg.sender` for this call is not authorized.\\n */\\n function getStakeInfo(address relayManager) external view returns (StakeInfo memory stakeInfo, bool isSenderAuthorizedHub);\\n\\n /**\\n * @return The maximum unstake delay this `StakeManger` allows. This is to prevent locking money forever by mistake.\\n */\\n function getMaxUnstakeDelay() external view returns (uint256);\\n\\n /**\\n * @notice Change the address that will receive the 'burned' part of the penalized stake.\\n * This is done to prevent malicious Relay Server from penalizing itself and breaking even.\\n */\\n function setBurnAddress(address _burnAddress) external;\\n\\n /**\\n * @return The address that will receive the 'burned' part of the penalized stake.\\n */\\n function getBurnAddress() external view returns (address);\\n\\n /**\\n * @notice Change the address that will receive the 'abandoned' stake.\\n * This is done to prevent Relay Servers that lost their keys from losing access to funds.\\n */\\n function setDevAddress(address _burnAddress) external;\\n\\n /**\\n * @return The structure that contains all configuration values for the 'abandoned' stake.\\n */\\n function getAbandonedRelayServerConfig() external view returns (AbandonedRelayServerConfig memory);\\n\\n /**\\n * @return the block number in which the contract has been deployed.\\n */\\n function getCreationBlock() external view returns (uint256);\\n\\n /**\\n * @return a SemVer-compliant version of the `StakeManager` contract.\\n */\\n function versionSM() external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x77035b55ca4c09cb499bc0cab3f9e791d77597b148dbfee8bf94ca6c0039c3e0\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/utils/GsnTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.0;\\n\\nimport \\\"../forwarder/IForwarder.sol\\\";\\n\\ninterface GsnTypes {\\n /// @notice maxFeePerGas, maxPriorityFeePerGas, pctRelayFee and baseRelayFee must be validated inside of the paymaster's preRelayedCall in order not to overpay\\n struct RelayData {\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n uint256 transactionCalldataGasUsed;\\n address relayWorker;\\n address paymaster;\\n address forwarder;\\n bytes paymasterData;\\n uint256 clientId;\\n }\\n\\n //note: must start with the ForwardRequest to be an extension of the generic forwarder\\n struct RelayRequest {\\n IForwarder.ForwardRequest request;\\n RelayData relayData;\\n }\\n}\\n\",\"keccak256\":\"0x9fb51c540f32939f1ee291e3fa709be64f7c73485bd7b87c6624c3567dd42a1b\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/utils/GsnUtils.sol\":{\"content\":\"/* solhint-disable no-inline-assembly */\\n// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/MinLibBytes.sol\\\";\\nimport \\\"./GsnTypes.sol\\\";\\n\\n/**\\n * @title The GSN Solidity Utils Library\\n * @notice Some library functions used throughout the GSN Solidity codebase.\\n */\\nlibrary GsnUtils {\\n\\n bytes32 constant private RELAY_REQUEST_ID_MASK = 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n /**\\n * @notice Calculate an identifier for the meta-transaction in a format similar to a transaction hash.\\n * Note that uniqueness relies on signature and may not be enforced if meta-transactions are verified\\n * with a different algorithm, e.g. when batching.\\n * @param relayRequest The `RelayRequest` for which an ID is being calculated.\\n * @param signature The signature for the `RelayRequest`. It is not validated here and may even remain empty.\\n */\\n function getRelayRequestID(GsnTypes.RelayRequest calldata relayRequest, bytes calldata signature)\\n internal\\n pure\\n returns (bytes32) {\\n return keccak256(abi.encode(relayRequest.request.from, relayRequest.request.nonce, signature)) & RELAY_REQUEST_ID_MASK;\\n }\\n\\n /**\\n * @notice Extract the method identifier signature from the encoded function call.\\n */\\n function getMethodSig(bytes memory msgData) internal pure returns (bytes4) {\\n return MinLibBytes.readBytes4(msgData, 0);\\n }\\n\\n /**\\n * @notice Extract a parameter from encoded-function block.\\n * see: https://solidity.readthedocs.io/en/develop/abi-spec.html#formal-specification-of-the-encoding\\n * The return value should be casted to the right type (`uintXXX`/`bytesXXX`/`address`/`bool`/`enum`).\\n * @param msgData Byte array containing a uint256 value.\\n * @param index Index in byte array of uint256 value.\\n * @return result uint256 value from byte array.\\n */\\n function getParam(bytes memory msgData, uint256 index) internal pure returns (uint256 result) {\\n return MinLibBytes.readUint256(msgData, 4 + index * 32);\\n }\\n\\n /// @notice Re-throw revert with the same revert data.\\n function revertWithData(bytes memory data) internal pure {\\n assembly {\\n revert(add(data,32), mload(data))\\n }\\n }\\n\\n}\\n\",\"keccak256\":\"0x7ea79bac2508612eba2c9372a7a4af953218b4ee2721e273f6d368e76b1ae7bb\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/utils/MinLibBytes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// minimal bytes manipulation required by GSN\\n// a minimal subset from 0x/LibBytes\\n/* solhint-disable no-inline-assembly */\\npragma solidity ^0.8.0;\\n\\nlibrary MinLibBytes {\\n\\n //truncate the given parameter (in-place) if its length is above the given maximum length\\n // do nothing otherwise.\\n //NOTE: solidity warns unless the method is marked \\\"pure\\\", but it DOES modify its parameter.\\n function truncateInPlace(bytes memory data, uint256 maxlen) internal pure {\\n if (data.length > maxlen) {\\n assembly { mstore(data, maxlen) }\\n }\\n }\\n\\n /// @dev Reads an address from a position in a byte array.\\n /// @param b Byte array containing an address.\\n /// @param index Index in byte array of address.\\n /// @return result address from byte array.\\n function readAddress(\\n bytes memory b,\\n uint256 index\\n )\\n internal\\n pure\\n returns (address result)\\n {\\n require (b.length >= index + 20, \\\"readAddress: data too short\\\");\\n\\n // Add offset to index:\\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\\n index += 20;\\n\\n // Read address from array memory\\n assembly {\\n // 1. Add index to address of bytes array\\n // 2. Load 32-byte word from memory\\n // 3. Apply 20-byte mask to obtain address\\n result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)\\n }\\n return result;\\n }\\n\\n function readBytes32(\\n bytes memory b,\\n uint256 index\\n )\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n require(b.length >= index + 32, \\\"readBytes32: data too short\\\" );\\n\\n // Read the bytes32 from array memory\\n assembly {\\n result := mload(add(b, add(index,32)))\\n }\\n return result;\\n }\\n\\n /// @dev Reads a uint256 value from a position in a byte array.\\n /// @param b Byte array containing a uint256 value.\\n /// @param index Index in byte array of uint256 value.\\n /// @return result uint256 value from byte array.\\n function readUint256(\\n bytes memory b,\\n uint256 index\\n )\\n internal\\n pure\\n returns (uint256 result)\\n {\\n result = uint256(readBytes32(b, index));\\n return result;\\n }\\n\\n function readBytes4(\\n bytes memory b,\\n uint256 index\\n )\\n internal\\n pure\\n returns (bytes4 result)\\n {\\n require(b.length >= index + 4, \\\"readBytes4: data too short\\\");\\n\\n // Read the bytes4 from array memory\\n assembly {\\n result := mload(add(b, add(index,32)))\\n // Solidity does not require us to clean the trailing bytes.\\n // We do it anyway\\n result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)\\n }\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x8063af8e0f134be3d794ad39bdc0041f33a16c91a4ee7abb968d4c15c8d10c54\",\"license\":\"MIT\"},\"@opengsn/contracts/src/utils/RLPReader.sol\":{\"content\":\"// SPDX-License-Identifier:APACHE-2.0\\n/*\\n* Taken from https://github.com/hamdiallam/Solidity-RLP\\n*/\\n/* solhint-disable */\\npragma solidity ^0.8.0;\\n\\nlibrary RLPReader {\\n\\n uint8 constant STRING_SHORT_START = 0x80;\\n uint8 constant STRING_LONG_START = 0xb8;\\n uint8 constant LIST_SHORT_START = 0xc0;\\n uint8 constant LIST_LONG_START = 0xf8;\\n uint8 constant WORD_SIZE = 32;\\n\\n struct RLPItem {\\n uint len;\\n uint memPtr;\\n }\\n\\n using RLPReader for bytes;\\n using RLPReader for uint;\\n using RLPReader for RLPReader.RLPItem;\\n\\n // helper function to decode rlp encoded legacy ethereum transaction\\n /*\\n * @param rawTransaction RLP encoded legacy ethereum transaction rlp([nonce, gasPrice, gasLimit, to, value, data]))\\n * @return tuple (nonce,gasLimit,to,value,data)\\n */\\n\\n function decodeLegacyTransaction(bytes calldata rawTransaction) internal pure returns (uint, uint, address, uint, bytes memory){\\n RLPReader.RLPItem[] memory values = rawTransaction.toRlpItem().toList(); // must convert to an rlpItem first!\\n return (values[0].toUint(), values[2].toUint(), values[3].toAddress(), values[4].toUint(), values[5].toBytes());\\n }\\n\\n /*\\n * @param rawTransaction format: 0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, access_list]))\\n * @return tuple (nonce,gasLimit,to,value,data)\\n */\\n function decodeTransactionType1(bytes calldata rawTransaction) internal pure returns (uint, uint, address, uint, bytes memory){\\n bytes memory payload = rawTransaction[1:rawTransaction.length];\\n RLPReader.RLPItem[] memory values = payload.toRlpItem().toList(); // must convert to an rlpItem first!\\n return (values[1].toUint(), values[3].toUint(), values[4].toAddress(), values[5].toUint(), values[6].toBytes());\\n }\\n\\n /*\\n * @param rawTransaction format: 0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list]))\\n * @return tuple (nonce,gasLimit,to,value,data)\\n */\\n function decodeTransactionType2(bytes calldata rawTransaction) internal pure returns (uint, uint, address, uint, bytes memory){\\n bytes memory payload = rawTransaction[1:rawTransaction.length];\\n RLPReader.RLPItem[] memory values = payload.toRlpItem().toList(); // must convert to an rlpItem first!\\n return (values[1].toUint(), values[4].toUint(), values[5].toAddress(), values[6].toUint(), values[7].toBytes());\\n }\\n\\n /*\\n * @param item RLP encoded bytes\\n */\\n function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {\\n if (item.length == 0)\\n return RLPItem(0, 0);\\n uint memPtr;\\n assembly {\\n memPtr := add(item, 0x20)\\n }\\n return RLPItem(item.length, memPtr);\\n }\\n /*\\n * @param item RLP encoded list in bytes\\n */\\n function toList(RLPItem memory item) internal pure returns (RLPItem[] memory result) {\\n require(isList(item), \\\"isList failed\\\");\\n uint items = numItems(item);\\n result = new RLPItem[](items);\\n uint memPtr = item.memPtr + _payloadOffset(item.memPtr);\\n uint dataLen;\\n for (uint i = 0; i < items; i++) {\\n dataLen = _itemLength(memPtr);\\n result[i] = RLPItem(dataLen, memPtr);\\n memPtr = memPtr + dataLen;\\n }\\n }\\n /*\\n * Helpers\\n */\\n // @return indicator whether encoded payload is a list. negate this function call for isData.\\n function isList(RLPItem memory item) internal pure returns (bool) {\\n uint8 byte0;\\n uint memPtr = item.memPtr;\\n assembly {\\n byte0 := byte(0, mload(memPtr))\\n }\\n if (byte0 < LIST_SHORT_START)\\n return false;\\n return true;\\n }\\n // @return number of payload items inside an encoded list.\\n function numItems(RLPItem memory item) internal pure returns (uint) {\\n uint count = 0;\\n uint currPtr = item.memPtr + _payloadOffset(item.memPtr);\\n uint endPtr = item.memPtr + item.len;\\n while (currPtr < endPtr) {\\n currPtr = currPtr + _itemLength(currPtr);\\n // skip over an item\\n count++;\\n }\\n return count;\\n }\\n // @return entire rlp item byte length\\n function _itemLength(uint memPtr) internal pure returns (uint len) {\\n uint byte0;\\n assembly {\\n byte0 := byte(0, mload(memPtr))\\n }\\n if (byte0 < STRING_SHORT_START)\\n return 1;\\n else if (byte0 < STRING_LONG_START)\\n return byte0 - STRING_SHORT_START + 1;\\n else if (byte0 < LIST_SHORT_START) {\\n assembly {\\n let byteLen := sub(byte0, 0xb7) // number of bytes the actual length is\\n memPtr := add(memPtr, 1) // skip over the first byte\\n /* 32 byte word size */\\n let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len\\n len := add(dataLen, add(byteLen, 1))\\n }\\n }\\n else if (byte0 < LIST_LONG_START) {\\n return byte0 - LIST_SHORT_START + 1;\\n }\\n else {\\n assembly {\\n let byteLen := sub(byte0, 0xf7)\\n memPtr := add(memPtr, 1)\\n let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length\\n len := add(dataLen, add(byteLen, 1))\\n }\\n }\\n }\\n // @return number of bytes until the data\\n function _payloadOffset(uint memPtr) internal pure returns (uint) {\\n uint byte0;\\n assembly {\\n byte0 := byte(0, mload(memPtr))\\n }\\n if (byte0 < STRING_SHORT_START)\\n return 0;\\n else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START))\\n return 1;\\n else if (byte0 < LIST_SHORT_START) // being explicit\\n return byte0 - (STRING_LONG_START - 1) + 1;\\n else\\n return byte0 - (LIST_LONG_START - 1) + 1;\\n }\\n /** RLPItem conversions into data types **/\\n // @returns raw rlp encoding in bytes\\n function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {\\n bytes memory result = new bytes(item.len);\\n uint ptr;\\n assembly {\\n ptr := add(0x20, result)\\n }\\n copy(item.memPtr, ptr, item.len);\\n return result;\\n }\\n\\n function toBoolean(RLPItem memory item) internal pure returns (bool) {\\n require(item.len == 1, \\\"Invalid RLPItem. Booleans are encoded in 1 byte\\\");\\n uint result;\\n uint memPtr = item.memPtr;\\n assembly {\\n result := byte(0, mload(memPtr))\\n }\\n return result == 0 ? false : true;\\n }\\n\\n function toAddress(RLPItem memory item) internal pure returns (address) {\\n // 1 byte for the length prefix according to RLP spec\\n require(item.len <= 21, \\\"Invalid RLPItem. Addresses are encoded in 20 bytes or less\\\");\\n return address(uint160(toUint(item)));\\n }\\n\\n function toUint(RLPItem memory item) internal pure returns (uint) {\\n uint offset = _payloadOffset(item.memPtr);\\n uint len = item.len - offset;\\n uint memPtr = item.memPtr + offset;\\n uint result;\\n assembly {\\n result := div(mload(memPtr), exp(256, sub(32, len))) // shift to the correct location\\n }\\n return result;\\n }\\n\\n function toBytes(RLPItem memory item) internal pure returns (bytes memory) {\\n uint offset = _payloadOffset(item.memPtr);\\n uint len = item.len - offset;\\n // data length\\n bytes memory result = new bytes(len);\\n uint destPtr;\\n assembly {\\n destPtr := add(0x20, result)\\n }\\n copy(item.memPtr + offset, destPtr, len);\\n return result;\\n }\\n /*\\n * @param src Pointer to source\\n * @param dest Pointer to destination\\n * @param len Amount of memory to copy from the source\\n */\\n function copy(uint src, uint dest, uint len) internal pure {\\n if (len == 0) return;\\n\\n // copy as many word sizes as possible\\n for (; len >= WORD_SIZE; len -= WORD_SIZE) {\\n assembly {\\n mstore(dest, mload(src))\\n }\\n\\n src += WORD_SIZE;\\n dest += WORD_SIZE;\\n }\\n\\n if (len > 0) {\\n // left over bytes. Mask is used to remove unwanted bytes from the word\\n uint mask = 256 ** (WORD_SIZE - len) - 1;\\n assembly {\\n let srcpart := and(mload(src), not(mask)) // zero out src\\n let destpart := and(mload(dest), mask) // retrieve the bytes\\n mstore(dest, or(destpart, srcpart))\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5d6a5a59e7f1724934daf1bbd662605f4b0031d90a02f16d34f4e11e6f12b0b8\",\"license\":\"APACHE-2.0\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\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 if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(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; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // 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 require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\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 + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x610120604052602960c08181529062001de860e03980516200002a916000916020909101906200006a565b503480156200003857600080fd5b5060405162001e1138038062001e118339810160408190526200005b9162000110565b60809190915260a05262000172565b828054620000789062000135565b90600052602060002090601f0160209004810192826200009c5760008555620000e7565b82601f10620000b757805160ff1916838001178555620000e7565b82800160010185558215620000e7579182015b82811115620000e7578251825591602001919060010190620000ca565b50620000f5929150620000f9565b5090565b5b80821115620000f55760008155600101620000fa565b600080604083850312156200012457600080fd5b505080516020909101519092909150565b600181811c908216806200014a57607f821691505b602082108114156200016c57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a051611c3b620001ad600039600081816101a40152818161047e01526105fb01526000818161011b015261068e0152611c3b6000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c8063a031365711610066578063a031365714610152578063a640bc7414610167578063ab456ccb1461017c578063f14fcbc81461018f578063fb509935146101a257600080fd5b806301ffc9a7146100a357806325896446146100cb57806347885781146100eb5780637f1a15bf146101195780638b29ee471461013f575b600080fd5b6100b66100b136600461171d565b6101c8565b60405190151581526020015b60405180910390f35b6100de6100d9366004611747565b6101ff565b6040516100c2919061197b565b61010b6100f9366004611704565b60016020526000908152604090205481565b6040519081526020016100c2565b7f000000000000000000000000000000000000000000000000000000000000000061010b565b6100b661014d366004611747565b6102bf565b61015a6102f2565b6040516100c29190611968565b61017a610175366004611867565b610380565b005b61017a61018a366004611789565b610502565b61017a61019d366004611704565b610687565b7f000000000000000000000000000000000000000000000000000000000000000061010b565b60006001600160e01b03198216636c18d0d560e11b14806101f957506301ffc9a760e01b6001600160e01b03198316145b92915050565b61023a6040518060a00160405280600081526020016000815260200160006001600160a01b0316815260200160008152602001606081525090565b6102448383610709565b15610277576102538383610730565b608086015260608501526001600160a01b03166040840152602083015281526101f9565b610281838361083b565b15610290576102538383610862565b61029a838361092c565b608086015260608501526001600160a01b031660408401526020830152815292915050565b60006102cb83836109fc565b806102db57506102db8383610709565b806102eb57506102eb838361083b565b9392505050565b600080546102ff90611b5d565b80601f016020809104026020016040519081016040528092919081815260200182805461032b90611b5d565b80156103785780601f1061034d57610100808354040283529160200191610378565b820191906000526020600020905b81548152906001019060200180831161035b57829003601f168201915b505050505081565b6000803660405161039292919061191c565b6040805191829003822060208301526001600160601b03193360601b169082015260540160408051601f1981840301815291815281516020928301206000818152600190935290822080549290559150336001600160a01b03146104eb578061042e5760405162461bcd60e51b81526020600482015260096024820152681b9bc818dbdb5b5a5d60ba1b60448201526064015b60405180910390fd5b4381106104785760405162461bcd60e51b81526020600482015260186024820152773932bb32b0b6103832b730b634bd32903a37b79039b7b7b760411b6044820152606401610425565b436104a37f0000000000000000000000000000000000000000000000000000000000000000836119f0565b116104eb5760405162461bcd60e51b815260206004820152601860248201527772657665616c2070656e616c697a6520746f6f206c61746560401b6044820152606401610425565b6104f88888888888610a3a565b5050505050505050565b6000803660405161051492919061191c565b6040805191829003822060208301526001600160601b03193360601b169082015260540160408051601f1981840301815291815281516020928301206000818152600190935290822080549290559150336001600160a01b031461066857806105ab5760405162461bcd60e51b81526020600482015260096024820152681b9bc818dbdb5b5a5d60ba1b6044820152606401610425565b4381106105f55760405162461bcd60e51b81526020600482015260186024820152773932bb32b0b6103832b730b634bd32903a37b79039b7b7b760411b6044820152606401610425565b436106207f0000000000000000000000000000000000000000000000000000000000000000836119f0565b116106685760405162461bcd60e51b815260206004820152601860248201527772657665616c2070656e616c697a6520746f6f206c61746560401b6044820152606401610425565b6106798c8c8c8c8c8c8c8c8c610ba4565b505050505050505050505050565b60006106b37f0000000000000000000000000000000000000000000000000000000000000000436119f0565b6000838152600160205260409081902082905551909150829033907fe3e71aede44b4dc2b562f1f86045529b7aadddc51e28f63a503f3b8ee937e16f906106fd9085815260200190565b60405180910390a35050565b60008282600081811061071e5761071e611bd9565b9091013560f81c600114949350505050565b6000808080606081610745876001818b6119c6565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093945061078f925061078a9150849050610e16565b610e67565b90506107b4816001815181106107a7576107a7611bd9565b6020026020010151610fac565b6107ca826003815181106107a7576107a7611bd9565b6107ed836004815181106107e0576107e0611bd9565b6020026020010151610ffa565b610803846005815181106107a7576107a7611bd9565b6108268560068151811061081957610819611bd9565b6020026020010151611080565b939d929c50909a509850909650945050505050565b60008282600081811061085057610850611bd9565b9091013560f81c600214949350505050565b6000808080606081610877876001818b6119c6565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509394506108bc925061078a9150849050610e16565b90506108d4816001815181106107a7576107a7611bd9565b6108ea826004815181106107a7576107a7611bd9565b610900836005815181106107e0576107e0611bd9565b610916846006815181106107a7576107a7611bd9565b6108268560078151811061081957610819611bd9565b6000806000806060600061097861078a89898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610e1692505050565b9050610990816000815181106107a7576107a7611bd9565b6109a6826002815181106107a7576107a7611bd9565b6109bc836003815181106107e0576107e0611bd9565b6109d2846004815181106107a7576107a7611bd9565b6109e88560058151811061081957610819611bd9565b939c929b5090995097509095509350505050565b60008083836000818110610a1257610a12611bd9565b919091013560f81c91505060c08110801590610a32575060fe8160ff1611155b949350505050565b610a4485856102bf565b15610aed576000610a5586866101ff565b9050816001600160a01b031681604001516001600160a01b03161415610aeb576000610a84826080015161111a565b90506001600160e01b03198116633654317160e11b141580610ae85760405162461bcd60e51b815260206004820152601760248201527f4c6567616c2072656c6179207472616e73616374696f6e0000000000000000006044820152606401610425565b50505b505b6000610b4784848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604051610b3892508a9150899061191c565b60405190819003902090611127565b90506001600160a01b038116610b925760405162461bcd60e51b815260206004820152601060248201526f1958dc9958dbdd995c8819985a5b195960821b6044820152606401610425565b610b9c818361114b565b505050505050565b6000610bef88888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604051610b3892508e91508d9061191c565b90506000610c3c85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604051610b3892508b91508a9061191c565b9050806001600160a01b0316826001600160a01b031614610c925760405162461bcd60e51b815260206004820152601060248201526f2234b33332b932b73a1039b4b3b732b960811b6044820152606401610425565b6001600160a01b038216610cdb5760405162461bcd60e51b815260206004820152601060248201526f1958dc9958dbdd995c8819985a5b195960821b6044820152606401610425565b6000610ce78c8c6101ff565b90506000610cf589896101ff565b8051835191925014610d3b5760405162461bcd60e51b815260206004820152600f60248201526e446966666572656e74206e6f6e636560881b6044820152606401610425565b60008260800151836020015184604001518560600151604051602001610d64949392919061192c565b604051602081830303815290604052905060008260800151836020015184604001518560600151604051602001610d9e949392919061192c565b6040516020818303038152906040529050808051906020012082805190602001201415610dfb5760405162461bcd60e51b815260206004820152600b60248201526a1d1e081a5cc8195c5d585b60aa1b6044820152606401610425565b610e05868861114b565b505050505050505050505050505050565b60408051808201909152600080825260208201528151610e49575050604080518082019091526000808252602082015290565b50604080518082019091528151815260209182019181019190915290565b6060610e72826111a8565b610eae5760405162461bcd60e51b815260206004820152600d60248201526c1a5cd31a5cdd0819985a5b1959609a1b6044820152606401610425565b6000610eb9836111d3565b90508067ffffffffffffffff811115610ed457610ed4611bef565b604051908082528060200260200182016040528015610f1957816020015b6040805180820190915260008082526020820152815260200190600190039081610ef25790505b5091506000610f2b846020015161124b565b8460200151610f3a91906119f0565b90506000805b83811015610fa357610f51836112cc565b9150604051806040016040528083815260200184815250858281518110610f7a57610f7a611bd9565b6020908102919091010152610f8f82846119f0565b925080610f9b81611b92565b915050610f40565b50505050919050565b600080610fbc836020015161124b565b90506000818460000151610fd09190611af3565b90506000828560200151610fe491906119f0565b516020929092036101000a909104949350505050565b60006015826000015111156110775760405162461bcd60e51b815260206004820152603a60248201527f496e76616c696420524c504974656d2e2041646472657373657320617265206560448201527f6e636f64656420696e203230206279746573206f72206c6573730000000000006064820152608401610425565b6101f982610fac565b60606000611091836020015161124b565b905060008184600001516110a59190611af3565b905060008167ffffffffffffffff8111156110c2576110c2611bef565b6040519080825280601f01601f1916602001820160405280156110ec576020820181803683370190505b509050600081602001905061111184876020015161110a91906119f0565b828561135b565b50949350505050565b60006101f98260006113db565b6000806000611136858561144b565b9150915061114381611491565b509392505050565b604051633af34c6b60e21b81526001600160a01b03838116600483015233602483015282169063ebcd31ac90604401600060405180830381600087803b15801561119457600080fd5b505af1158015610b9c573d6000803e3d6000fd5b6020810151805160009190821a9060c08210156111c9575060009392505050565b5060019392505050565b6000806000905060006111e9846020015161124b565b84602001516111f891906119f0565b905060008460000151856020015161121091906119f0565b90505b8082101561124257611224826112cc565b61122e90836119f0565b91508261123a81611b92565b935050611213565b50909392505050565b8051600090811a60808110156112645750600092915050565b60b881108061127f575060c0811080159061127f575060f881105b1561128d5750600192915050565b60c08110156112ba576112a2600160b8611b0a565b6112af9060ff1682611af3565b6102eb9060016119f0565b6112a2600160f8611b0a565b50919050565b8051600090811a60808110156112e55750600192915050565b60b88110156112f9576112af608082611af3565b60c08110156113265760b78103600184019350806020036101000a845104600182018101935050506112c6565b60f881101561133a576112af60c082611af3565b60019290920151602083900360f7016101000a900490910160f51901919050565b8061136557505050565b6020811061139d578251825261137c6020846119f0565b92506113896020836119f0565b9150611396602082611af3565b9050611365565b80156113d657600060016113b2836020611af3565b6113be90610100611a4b565b6113c89190611af3565b845184518216911916178352505b505050565b60006113e88260046119f0565b835110156114385760405162461bcd60e51b815260206004820152601a60248201527f726561644279746573343a206461746120746f6f2073686f72740000000000006044820152606401610425565b5001602001516001600160e01b03191690565b6000808251604114156114825760208301516040840151606085015160001a611476878285856115e2565b9450945050505061148a565b506000905060025b9250929050565b60008160048111156114a5576114a5611bc3565b14156114ae5750565b60018160048111156114c2576114c2611bc3565b14156115105760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610425565b600281600481111561152457611524611bc3565b14156115725760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610425565b600381600481111561158657611586611bc3565b14156115df5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610425565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611619575060009050600361169d565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561166d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166116965760006001925092505061169d565b9150600090505b94509492505050565b60008083601f8401126116b857600080fd5b50813567ffffffffffffffff8111156116d057600080fd5b60208301915083602082850101111561148a57600080fd5b80356001600160a01b03811681146116ff57600080fd5b919050565b60006020828403121561171657600080fd5b5035919050565b60006020828403121561172f57600080fd5b81356001600160e01b0319811681146102eb57600080fd5b6000806020838503121561175a57600080fd5b823567ffffffffffffffff81111561177157600080fd5b61177d858286016116a6565b90969095509350505050565b60008060008060008060008060008060c08b8d0312156117a857600080fd5b8a3567ffffffffffffffff808211156117c057600080fd5b6117cc8e838f016116a6565b909c509a5060208d01359150808211156117e557600080fd5b6117f18e838f016116a6565b909a50985060408d013591508082111561180a57600080fd5b6118168e838f016116a6565b909850965060608d013591508082111561182f57600080fd5b5061183c8d828e016116a6565b909550935061184f905060808c016116e8565b915060a08b013590509295989b9194979a5092959850565b6000806000806000806080878903121561188057600080fd5b863567ffffffffffffffff8082111561189857600080fd5b6118a48a838b016116a6565b909850965060208901359150808211156118bd57600080fd5b506118ca89828a016116a6565b90955093506118dd9050604088016116e8565b9150606087013590509295509295509295565b60008151808452611908816020860160208601611b2d565b601f01601f19169290920160200192915050565b8183823760009101908152919050565b6000855161193e818460208a01611b2d565b919091019384525060609190911b6001600160601b03191660208301526034820152605401919050565b6020815260006102eb60208301846118f0565b60208152815160208201526020820151604082015260018060a01b036040830151166060820152606082015160808201526000608083015160a080840152610a3260c08401826118f0565b600080858511156119d657600080fd5b838611156119e357600080fd5b5050820193919092039150565b60008219821115611a0357611a03611bad565b500190565b600181815b80851115611a43578160001904821115611a2957611a29611bad565b80851615611a3657918102915b93841c9390800290611a0d565b509250929050565b60006102eb8383600082611a61575060016101f9565b81611a6e575060006101f9565b8160018114611a845760028114611a8e57611aaa565b60019150506101f9565b60ff841115611a9f57611a9f611bad565b50506001821b6101f9565b5060208310610133831016604e8410600b8410161715611acd575081810a6101f9565b611ad78383611a08565b8060001904821115611aeb57611aeb611bad565b029392505050565b600082821015611b0557611b05611bad565b500390565b600060ff821660ff841680821015611b2457611b24611bad565b90039392505050565b60005b83811015611b48578181015183820152602001611b30565b83811115611b57576000848401525b50505050565b600181811c90821680611b7157607f821691505b602082108114156112c657634e487b7160e01b600052602260045260246000fd5b6000600019821415611ba657611ba6611bad565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220fa0dfcc4dbb83ddc5bf5266c96c0053a2be0fdd808caa24b399c54d3aaf5eecc64736f6c63430008070033332e302e302d626574612e332b6f70656e67736e2e70656e616c697a65722e6970656e616c697a6572", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061009e5760003560e01c8063a031365711610066578063a031365714610152578063a640bc7414610167578063ab456ccb1461017c578063f14fcbc81461018f578063fb509935146101a257600080fd5b806301ffc9a7146100a357806325896446146100cb57806347885781146100eb5780637f1a15bf146101195780638b29ee471461013f575b600080fd5b6100b66100b136600461171d565b6101c8565b60405190151581526020015b60405180910390f35b6100de6100d9366004611747565b6101ff565b6040516100c2919061197b565b61010b6100f9366004611704565b60016020526000908152604090205481565b6040519081526020016100c2565b7f000000000000000000000000000000000000000000000000000000000000000061010b565b6100b661014d366004611747565b6102bf565b61015a6102f2565b6040516100c29190611968565b61017a610175366004611867565b610380565b005b61017a61018a366004611789565b610502565b61017a61019d366004611704565b610687565b7f000000000000000000000000000000000000000000000000000000000000000061010b565b60006001600160e01b03198216636c18d0d560e11b14806101f957506301ffc9a760e01b6001600160e01b03198316145b92915050565b61023a6040518060a00160405280600081526020016000815260200160006001600160a01b0316815260200160008152602001606081525090565b6102448383610709565b15610277576102538383610730565b608086015260608501526001600160a01b03166040840152602083015281526101f9565b610281838361083b565b15610290576102538383610862565b61029a838361092c565b608086015260608501526001600160a01b031660408401526020830152815292915050565b60006102cb83836109fc565b806102db57506102db8383610709565b806102eb57506102eb838361083b565b9392505050565b600080546102ff90611b5d565b80601f016020809104026020016040519081016040528092919081815260200182805461032b90611b5d565b80156103785780601f1061034d57610100808354040283529160200191610378565b820191906000526020600020905b81548152906001019060200180831161035b57829003601f168201915b505050505081565b6000803660405161039292919061191c565b6040805191829003822060208301526001600160601b03193360601b169082015260540160408051601f1981840301815291815281516020928301206000818152600190935290822080549290559150336001600160a01b03146104eb578061042e5760405162461bcd60e51b81526020600482015260096024820152681b9bc818dbdb5b5a5d60ba1b60448201526064015b60405180910390fd5b4381106104785760405162461bcd60e51b81526020600482015260186024820152773932bb32b0b6103832b730b634bd32903a37b79039b7b7b760411b6044820152606401610425565b436104a37f0000000000000000000000000000000000000000000000000000000000000000836119f0565b116104eb5760405162461bcd60e51b815260206004820152601860248201527772657665616c2070656e616c697a6520746f6f206c61746560401b6044820152606401610425565b6104f88888888888610a3a565b5050505050505050565b6000803660405161051492919061191c565b6040805191829003822060208301526001600160601b03193360601b169082015260540160408051601f1981840301815291815281516020928301206000818152600190935290822080549290559150336001600160a01b031461066857806105ab5760405162461bcd60e51b81526020600482015260096024820152681b9bc818dbdb5b5a5d60ba1b6044820152606401610425565b4381106105f55760405162461bcd60e51b81526020600482015260186024820152773932bb32b0b6103832b730b634bd32903a37b79039b7b7b760411b6044820152606401610425565b436106207f0000000000000000000000000000000000000000000000000000000000000000836119f0565b116106685760405162461bcd60e51b815260206004820152601860248201527772657665616c2070656e616c697a6520746f6f206c61746560401b6044820152606401610425565b6106798c8c8c8c8c8c8c8c8c610ba4565b505050505050505050505050565b60006106b37f0000000000000000000000000000000000000000000000000000000000000000436119f0565b6000838152600160205260409081902082905551909150829033907fe3e71aede44b4dc2b562f1f86045529b7aadddc51e28f63a503f3b8ee937e16f906106fd9085815260200190565b60405180910390a35050565b60008282600081811061071e5761071e611bd9565b9091013560f81c600114949350505050565b6000808080606081610745876001818b6119c6565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093945061078f925061078a9150849050610e16565b610e67565b90506107b4816001815181106107a7576107a7611bd9565b6020026020010151610fac565b6107ca826003815181106107a7576107a7611bd9565b6107ed836004815181106107e0576107e0611bd9565b6020026020010151610ffa565b610803846005815181106107a7576107a7611bd9565b6108268560068151811061081957610819611bd9565b6020026020010151611080565b939d929c50909a509850909650945050505050565b60008282600081811061085057610850611bd9565b9091013560f81c600214949350505050565b6000808080606081610877876001818b6119c6565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509394506108bc925061078a9150849050610e16565b90506108d4816001815181106107a7576107a7611bd9565b6108ea826004815181106107a7576107a7611bd9565b610900836005815181106107e0576107e0611bd9565b610916846006815181106107a7576107a7611bd9565b6108268560078151811061081957610819611bd9565b6000806000806060600061097861078a89898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610e1692505050565b9050610990816000815181106107a7576107a7611bd9565b6109a6826002815181106107a7576107a7611bd9565b6109bc836003815181106107e0576107e0611bd9565b6109d2846004815181106107a7576107a7611bd9565b6109e88560058151811061081957610819611bd9565b939c929b5090995097509095509350505050565b60008083836000818110610a1257610a12611bd9565b919091013560f81c91505060c08110801590610a32575060fe8160ff1611155b949350505050565b610a4485856102bf565b15610aed576000610a5586866101ff565b9050816001600160a01b031681604001516001600160a01b03161415610aeb576000610a84826080015161111a565b90506001600160e01b03198116633654317160e11b141580610ae85760405162461bcd60e51b815260206004820152601760248201527f4c6567616c2072656c6179207472616e73616374696f6e0000000000000000006044820152606401610425565b50505b505b6000610b4784848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604051610b3892508a9150899061191c565b60405190819003902090611127565b90506001600160a01b038116610b925760405162461bcd60e51b815260206004820152601060248201526f1958dc9958dbdd995c8819985a5b195960821b6044820152606401610425565b610b9c818361114b565b505050505050565b6000610bef88888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604051610b3892508e91508d9061191c565b90506000610c3c85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604051610b3892508b91508a9061191c565b9050806001600160a01b0316826001600160a01b031614610c925760405162461bcd60e51b815260206004820152601060248201526f2234b33332b932b73a1039b4b3b732b960811b6044820152606401610425565b6001600160a01b038216610cdb5760405162461bcd60e51b815260206004820152601060248201526f1958dc9958dbdd995c8819985a5b195960821b6044820152606401610425565b6000610ce78c8c6101ff565b90506000610cf589896101ff565b8051835191925014610d3b5760405162461bcd60e51b815260206004820152600f60248201526e446966666572656e74206e6f6e636560881b6044820152606401610425565b60008260800151836020015184604001518560600151604051602001610d64949392919061192c565b604051602081830303815290604052905060008260800151836020015184604001518560600151604051602001610d9e949392919061192c565b6040516020818303038152906040529050808051906020012082805190602001201415610dfb5760405162461bcd60e51b815260206004820152600b60248201526a1d1e081a5cc8195c5d585b60aa1b6044820152606401610425565b610e05868861114b565b505050505050505050505050505050565b60408051808201909152600080825260208201528151610e49575050604080518082019091526000808252602082015290565b50604080518082019091528151815260209182019181019190915290565b6060610e72826111a8565b610eae5760405162461bcd60e51b815260206004820152600d60248201526c1a5cd31a5cdd0819985a5b1959609a1b6044820152606401610425565b6000610eb9836111d3565b90508067ffffffffffffffff811115610ed457610ed4611bef565b604051908082528060200260200182016040528015610f1957816020015b6040805180820190915260008082526020820152815260200190600190039081610ef25790505b5091506000610f2b846020015161124b565b8460200151610f3a91906119f0565b90506000805b83811015610fa357610f51836112cc565b9150604051806040016040528083815260200184815250858281518110610f7a57610f7a611bd9565b6020908102919091010152610f8f82846119f0565b925080610f9b81611b92565b915050610f40565b50505050919050565b600080610fbc836020015161124b565b90506000818460000151610fd09190611af3565b90506000828560200151610fe491906119f0565b516020929092036101000a909104949350505050565b60006015826000015111156110775760405162461bcd60e51b815260206004820152603a60248201527f496e76616c696420524c504974656d2e2041646472657373657320617265206560448201527f6e636f64656420696e203230206279746573206f72206c6573730000000000006064820152608401610425565b6101f982610fac565b60606000611091836020015161124b565b905060008184600001516110a59190611af3565b905060008167ffffffffffffffff8111156110c2576110c2611bef565b6040519080825280601f01601f1916602001820160405280156110ec576020820181803683370190505b509050600081602001905061111184876020015161110a91906119f0565b828561135b565b50949350505050565b60006101f98260006113db565b6000806000611136858561144b565b9150915061114381611491565b509392505050565b604051633af34c6b60e21b81526001600160a01b03838116600483015233602483015282169063ebcd31ac90604401600060405180830381600087803b15801561119457600080fd5b505af1158015610b9c573d6000803e3d6000fd5b6020810151805160009190821a9060c08210156111c9575060009392505050565b5060019392505050565b6000806000905060006111e9846020015161124b565b84602001516111f891906119f0565b905060008460000151856020015161121091906119f0565b90505b8082101561124257611224826112cc565b61122e90836119f0565b91508261123a81611b92565b935050611213565b50909392505050565b8051600090811a60808110156112645750600092915050565b60b881108061127f575060c0811080159061127f575060f881105b1561128d5750600192915050565b60c08110156112ba576112a2600160b8611b0a565b6112af9060ff1682611af3565b6102eb9060016119f0565b6112a2600160f8611b0a565b50919050565b8051600090811a60808110156112e55750600192915050565b60b88110156112f9576112af608082611af3565b60c08110156113265760b78103600184019350806020036101000a845104600182018101935050506112c6565b60f881101561133a576112af60c082611af3565b60019290920151602083900360f7016101000a900490910160f51901919050565b8061136557505050565b6020811061139d578251825261137c6020846119f0565b92506113896020836119f0565b9150611396602082611af3565b9050611365565b80156113d657600060016113b2836020611af3565b6113be90610100611a4b565b6113c89190611af3565b845184518216911916178352505b505050565b60006113e88260046119f0565b835110156114385760405162461bcd60e51b815260206004820152601a60248201527f726561644279746573343a206461746120746f6f2073686f72740000000000006044820152606401610425565b5001602001516001600160e01b03191690565b6000808251604114156114825760208301516040840151606085015160001a611476878285856115e2565b9450945050505061148a565b506000905060025b9250929050565b60008160048111156114a5576114a5611bc3565b14156114ae5750565b60018160048111156114c2576114c2611bc3565b14156115105760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610425565b600281600481111561152457611524611bc3565b14156115725760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610425565b600381600481111561158657611586611bc3565b14156115df5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610425565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611619575060009050600361169d565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561166d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166116965760006001925092505061169d565b9150600090505b94509492505050565b60008083601f8401126116b857600080fd5b50813567ffffffffffffffff8111156116d057600080fd5b60208301915083602082850101111561148a57600080fd5b80356001600160a01b03811681146116ff57600080fd5b919050565b60006020828403121561171657600080fd5b5035919050565b60006020828403121561172f57600080fd5b81356001600160e01b0319811681146102eb57600080fd5b6000806020838503121561175a57600080fd5b823567ffffffffffffffff81111561177157600080fd5b61177d858286016116a6565b90969095509350505050565b60008060008060008060008060008060c08b8d0312156117a857600080fd5b8a3567ffffffffffffffff808211156117c057600080fd5b6117cc8e838f016116a6565b909c509a5060208d01359150808211156117e557600080fd5b6117f18e838f016116a6565b909a50985060408d013591508082111561180a57600080fd5b6118168e838f016116a6565b909850965060608d013591508082111561182f57600080fd5b5061183c8d828e016116a6565b909550935061184f905060808c016116e8565b915060a08b013590509295989b9194979a5092959850565b6000806000806000806080878903121561188057600080fd5b863567ffffffffffffffff8082111561189857600080fd5b6118a48a838b016116a6565b909850965060208901359150808211156118bd57600080fd5b506118ca89828a016116a6565b90955093506118dd9050604088016116e8565b9150606087013590509295509295509295565b60008151808452611908816020860160208601611b2d565b601f01601f19169290920160200192915050565b8183823760009101908152919050565b6000855161193e818460208a01611b2d565b919091019384525060609190911b6001600160601b03191660208301526034820152605401919050565b6020815260006102eb60208301846118f0565b60208152815160208201526020820151604082015260018060a01b036040830151166060820152606082015160808201526000608083015160a080840152610a3260c08401826118f0565b600080858511156119d657600080fd5b838611156119e357600080fd5b5050820193919092039150565b60008219821115611a0357611a03611bad565b500190565b600181815b80851115611a43578160001904821115611a2957611a29611bad565b80851615611a3657918102915b93841c9390800290611a0d565b509250929050565b60006102eb8383600082611a61575060016101f9565b81611a6e575060006101f9565b8160018114611a845760028114611a8e57611aaa565b60019150506101f9565b60ff841115611a9f57611a9f611bad565b50506001821b6101f9565b5060208310610133831016604e8410600b8410161715611acd575081810a6101f9565b611ad78383611a08565b8060001904821115611aeb57611aeb611bad565b029392505050565b600082821015611b0557611b05611bad565b500390565b600060ff821660ff841680821015611b2457611b24611bad565b90039392505050565b60005b83811015611b48578181015183820152602001611b30565b83811115611b57576000848401525b50505050565b600181811c90821680611b7157607f821691505b602082108114156112c657634e487b7160e01b600052602260045260246000fd5b6000600019821415611ba657611ba6611bad565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220fa0dfcc4dbb83ddc5bf5266c96c0053a2be0fdd808caa24b399c54d3aaf5eecc64736f6c63430008070033", + "devdoc": { + "kind": "dev", + "methods": { + "commit(bytes32)": { + "params": { + "commitHash": "The hash of the report of a penalizable behaviour the reporter wants to reveal. Calculated as `commit(keccak(encodedPenalizeFunction))`." + } + }, + "decodeTransaction(bytes)": { + "returns": { + "transaction": "The details that the `Penalizer` needs to decide if the transaction is penalizable." + } + }, + "getPenalizeBlockDelay()": { + "returns": { + "_0": "The minimum delay between commit and reveal steps." + } + }, + "getPenalizeBlockExpiration()": { + "returns": { + "_0": "The maximum delay between commit and reveal steps." + } + }, + "isTransactionTypeValid(bytes)": { + "returns": { + "_0": "`true` if raw transaction is of types Legacy, 1 or 2. `false` otherwise." + } + }, + "supportsInterface(bytes4)": { + "details": "Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas." + } + }, + "stateVariables": { + "versionPenalizer": { + "return": "a SemVer-compliant version of the `Penalizer` contract.", + "returns": { + "_0": "a SemVer-compliant version of the `Penalizer` contract." + } + } + }, + "title": "The Penalizer Implementation", + "version": 1 + }, + "userdoc": { + "events": { + "CommitAdded(address,bytes32,uint256)": { + "notice": "Emitted once the reporter submits the first step in the commit-reveal process." + } + }, + "kind": "user", + "methods": { + "commit(bytes32)": { + "notice": "Called by the reporter as the first step in the commit-reveal process. Any sender can call it to make sure no-one can front-run it to claim this penalization." + }, + "penalizeIllegalTransaction(bytes,bytes,address,uint256)": { + "notice": "Called by the reporter as the second step in the commit-reveal process. The Relay Workers are not allowed to make calls other than to the `relayCall` method." + }, + "penalizeRepeatedNonce(bytes,bytes,bytes,bytes,address,uint256)": { + "notice": "Called by the reporter as the second step in the commit-reveal process. If a Relay Worker attacked the system by signing multiple transactions with same nonce so only one is accepted, anyone can grab both transactions from the blockchain and submit them here. Check whether `unsignedTx1` != `unsignedTx2`, that both are signed by the same address, and that `unsignedTx1.nonce` == `unsignedTx2.nonce`. If all conditions are met, relay is considered an \"offending relay\". The offending relay will be unregistered immediately, its stake will be forfeited and given to the address who reported it (the `msg.sender`), thus incentivizing anyone to report offending relays." + } + }, + "notice": "This Penalizer supports parsing Legacy, Type 1 and Type 2 raw RLP Encoded transactions.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 522, + "contract": "@opengsn/contracts/src/Penalizer.sol:Penalizer", + "label": "versionPenalizer", + "offset": 0, + "slot": "0", + "type": "t_string_storage" + }, + { + "astId": 750, + "contract": "@opengsn/contracts/src/Penalizer.sol:Penalizer", + "label": "commits", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "types": { + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/gsn/deploy/data/deployments/amoy/RelayHub.json b/gsn/deploy/data/deployments/amoy/RelayHub.json new file mode 100644 index 00000000..668a6de3 --- /dev/null +++ b/gsn/deploy/data/deployments/amoy/RelayHub.json @@ -0,0 +1,1865 @@ +{ + "address": "0x1fF8D9c74FC2D9a9FD18E6B3Acf6D5A5846B6A00", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IStakeManager", + "name": "_stakeManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_penalizer", + "type": "address" + }, + { + "internalType": "address", + "name": "_batchGateway", + "type": "address" + }, + { + "internalType": "address", + "name": "_relayRegistrar", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "maxWorkerCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasReserve", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "postOverhead", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasOverhead", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumUnstakeDelay", + "type": "uint256" + }, + { + "internalType": "address", + "name": "devAddress", + "type": "address" + }, + { + "internalType": "uint8", + "name": "devFee", + "type": "uint8" + }, + { + "internalType": "uint80", + "name": "baseRelayFee", + "type": "uint80" + }, + { + "internalType": "uint16", + "name": "pctRelayFee", + "type": "uint16" + } + ], + "internalType": "struct IRelayHub.RelayHubConfig", + "name": "_config", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "name": "AbandonedRelayManagerBalanceEscheated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "paymaster", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "deprecationTime", + "type": "uint256" + } + ], + "name": "HubDeprecated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "maxWorkerCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasReserve", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "postOverhead", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasOverhead", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumUnstakeDelay", + "type": "uint256" + }, + { + "internalType": "address", + "name": "devAddress", + "type": "address" + }, + { + "internalType": "uint8", + "name": "devFee", + "type": "uint8" + }, + { + "internalType": "uint80", + "name": "baseRelayFee", + "type": "uint80" + }, + { + "internalType": "uint16", + "name": "pctRelayFee", + "type": "uint16" + } + ], + "indexed": false, + "internalType": "struct IRelayHub.RelayHubConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "RelayHubConfigured", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "newRelayWorkers", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "workersCount", + "type": "uint256" + } + ], + "name": "RelayWorkersAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "minimumStake", + "type": "uint256" + } + ], + "name": "StakingTokenDataChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "paymaster", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "relayRequestID", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "relayWorker", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "innerGasUsed", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "reason", + "type": "bytes" + } + ], + "name": "TransactionRejectedByPaymaster", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "relayWorker", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "relayRequestID", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "paymaster", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "enum IRelayHub.RelayCallStatus", + "name": "status", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "charge", + "type": "uint256" + } + ], + "name": "TransactionRelayed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum IRelayHub.RelayCallStatus", + "name": "status", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "returnValue", + "type": "bytes" + } + ], + "name": "TransactionResult", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dest", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "newRelayWorkers", + "type": "address[]" + } + ], + "name": "addRelayWorkers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "aggregateGasleft", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "gasUsed", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "transactionCalldataGasUsed", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayWorker", + "type": "address" + }, + { + "internalType": "address", + "name": "paymaster", + "type": "address" + }, + { + "internalType": "address", + "name": "forwarder", + "type": "address" + }, + { + "internalType": "bytes", + "name": "paymasterData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "clientId", + "type": "uint256" + } + ], + "internalType": "struct GsnTypes.RelayData", + "name": "relayData", + "type": "tuple" + } + ], + "name": "calculateCharge", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "charge", + "type": "uint256" + } + ], + "name": "calculateDevCharge", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "depositFor", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_deprecationTime", + "type": "uint256" + } + ], + "name": "deprecateHub", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "name": "escheatAbandonedRelayBalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBatchGateway", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getConfiguration", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "maxWorkerCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasReserve", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "postOverhead", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasOverhead", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumUnstakeDelay", + "type": "uint256" + }, + { + "internalType": "address", + "name": "devAddress", + "type": "address" + }, + { + "internalType": "uint8", + "name": "devFee", + "type": "uint8" + }, + { + "internalType": "uint80", + "name": "baseRelayFee", + "type": "uint80" + }, + { + "internalType": "uint16", + "name": "pctRelayFee", + "type": "uint16" + } + ], + "internalType": "struct IRelayHub.RelayHubConfig", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDeprecationTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "getMinimumStakePerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPenalizer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayRegistrar", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStakeManager", + "outputs": [ + { + "internalType": "contract IStakeManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "getWorkerCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "worker", + "type": "address" + } + ], + "name": "getWorkerManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "domainSeparatorName", + "type": "string" + }, + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "validUntilTime", + "type": "uint256" + } + ], + "internalType": "struct IForwarder.ForwardRequest", + "name": "request", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "transactionCalldataGasUsed", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayWorker", + "type": "address" + }, + { + "internalType": "address", + "name": "paymaster", + "type": "address" + }, + { + "internalType": "address", + "name": "forwarder", + "type": "address" + }, + { + "internalType": "bytes", + "name": "paymasterData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "clientId", + "type": "uint256" + } + ], + "internalType": "struct GsnTypes.RelayData", + "name": "relayData", + "type": "tuple" + } + ], + "internalType": "struct GsnTypes.RelayRequest", + "name": "relayRequest", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "approvalData", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "acceptanceBudget", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preRelayedCallGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "postRelayedCallGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "calldataSizeLimit", + "type": "uint256" + } + ], + "internalType": "struct IPaymaster.GasAndDataLimits", + "name": "gasAndDataLimits", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "totalInitialGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPossibleGas", + "type": "uint256" + } + ], + "name": "innerRelayCall", + "outputs": [ + { + "internalType": "enum IRelayHub.RelayCallStatus", + "name": "", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isDeprecated", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "name": "isRelayEscheatable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "name": "onRelayServerRegistered", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayWorker", + "type": "address" + }, + { + "internalType": "address payable", + "name": "beneficiary", + "type": "address" + } + ], + "name": "penalize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "domainSeparatorName", + "type": "string" + }, + { + "internalType": "uint256", + "name": "maxAcceptanceBudget", + "type": "uint256" + }, + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "validUntilTime", + "type": "uint256" + } + ], + "internalType": "struct IForwarder.ForwardRequest", + "name": "request", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "transactionCalldataGasUsed", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayWorker", + "type": "address" + }, + { + "internalType": "address", + "name": "paymaster", + "type": "address" + }, + { + "internalType": "address", + "name": "forwarder", + "type": "address" + }, + { + "internalType": "bytes", + "name": "paymasterData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "clientId", + "type": "uint256" + } + ], + "internalType": "struct GsnTypes.RelayData", + "name": "relayData", + "type": "tuple" + } + ], + "internalType": "struct GsnTypes.RelayRequest", + "name": "relayRequest", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "approvalData", + "type": "bytes" + } + ], + "name": "relayCall", + "outputs": [ + { + "internalType": "bool", + "name": "paymasterAccepted", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "charge", + "type": "uint256" + }, + { + "internalType": "enum IRelayHub.RelayCallStatus", + "name": "status", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "returnValue", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "maxWorkerCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasReserve", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "postOverhead", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasOverhead", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumUnstakeDelay", + "type": "uint256" + }, + { + "internalType": "address", + "name": "devAddress", + "type": "address" + }, + { + "internalType": "uint8", + "name": "devFee", + "type": "uint8" + }, + { + "internalType": "uint80", + "name": "baseRelayFee", + "type": "uint80" + }, + { + "internalType": "uint16", + "name": "pctRelayFee", + "type": "uint16" + } + ], + "internalType": "struct IRelayHub.RelayHubConfig", + "name": "_config", + "type": "tuple" + } + ], + "name": "setConfiguration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "token", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "minimumStake", + "type": "uint256[]" + } + ], + "name": "setMinimumStakes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "name": "verifyRelayManagerStaked", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "versionHub", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable[]", + "name": "dest", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amount", + "type": "uint256[]" + } + ], + "name": "withdrawMultiple", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x23f37ebf8ead55499fe23b780ce548a0f6903dd4e549fa0cdf73fad464506a05", + "receipt": { + "to": null, + "from": "0x61B1E290d2F465d6667336d4934941aa2517AfA2", + "contractAddress": "0x1fF8D9c74FC2D9a9FD18E6B3Acf6D5A5846B6A00", + "transactionIndex": 0, + "gasUsed": "4770739", + "logsBloom": "0x00000000000000000008000000000000000000000000000000800000000000000000000000000002000000000000000000008000000000000000010000000000000000000000000000080000000000800001000000000000000100000000000000000000020000000000000000000800008000000000000080000000000000400000000100000000001000000000000000004000000000000000000000000000200000000000000000020000000000000000000000000000000000000000004000000000000000008001000000000000000000000000000000100000000020000000000000000000000040010000000000000000000000000000000000100000", + "blockHash": "0x91daeaf8df5cab617909b95c182369b26407fec033e0ec6aed5a487c8f29f24d", + "transactionHash": "0x23f37ebf8ead55499fe23b780ce548a0f6903dd4e549fa0cdf73fad464506a05", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 4880299, + "transactionHash": "0x23f37ebf8ead55499fe23b780ce548a0f6903dd4e549fa0cdf73fad464506a05", + "address": "0x1fF8D9c74FC2D9a9FD18E6B3Acf6D5A5846B6A00", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000061b1e290d2f465d6667336d4934941aa2517afa2" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x91daeaf8df5cab617909b95c182369b26407fec033e0ec6aed5a487c8f29f24d" + }, + { + "transactionIndex": 0, + "blockNumber": 4880299, + "transactionHash": "0x23f37ebf8ead55499fe23b780ce548a0f6903dd4e549fa0cdf73fad464506a05", + "address": "0x1fF8D9c74FC2D9a9FD18E6B3Acf6D5A5846B6A00", + "topics": [ + "0x4812ada68f7c2cdc9f4a4a09e157ea6b924e0ef40a4fa7aa074fa8f70b1e7247" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000009674000000000000000000000000000000000000000000000000000000000000885d0000000000000000000000000000000000000000000000000000000000003a9800000000000000000000000061b1e290d2f465d6667336d4934941aa2517afa2000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 1, + "blockHash": "0x91daeaf8df5cab617909b95c182369b26407fec033e0ec6aed5a487c8f29f24d" + }, + { + "transactionIndex": 0, + "blockNumber": 4880299, + "transactionHash": "0x23f37ebf8ead55499fe23b780ce548a0f6903dd4e549fa0cdf73fad464506a05", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x00000000000000000000000061b1e290d2f465d6667336d4934941aa2517afa2", + "0x00000000000000000000000009207a6efee346cb3e4a54ac18523e3715d38b3f" + ], + "data": "0x00000000000000000000000000000000000000000000000003f8f1b5e8669883000000000000000000000000000000000000000000000000088e613e7c71400000000000000000000000000000000000000000000000000e3dba0642cbebaa7d00000000000000000000000000000000000000000000000004956f88940aa77d00000000000000000000000000000000000000000000000e41b2f7f8b4524300", + "logIndex": 2, + "blockHash": "0x91daeaf8df5cab617909b95c182369b26407fec033e0ec6aed5a487c8f29f24d" + } + ], + "blockNumber": 4880299, + "cumulativeGasUsed": "4770739", + "status": 1, + "byzantium": true + }, + "args": [ + "0x542B24678Ee3c319EBE006aD677cf8Ce4C6F97b0", + "0x6d57Dff87ED83c85Bcd79560AFc95004F398D6E2", + "0x0000000000000000000000000000000000000000", + "0x789A9BdA84A4aE86aCC8797971197729C3bfc42a", + { + "gasOverhead": 34909, + "postOverhead": 38516, + "gasReserve": 100000, + "maxWorkerCount": 10, + "minimumUnstakeDelay": 15000, + "devAddress": "0x61B1E290d2F465d6667336d4934941aa2517AfA2", + "devFee": 10, + "pctRelayFee": 0, + "baseRelayFee": 0 + } + ], + "numDeployments": 1, + "solcInputHash": "766eaa539015b343a6f8732a84d5a9ae", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IStakeManager\",\"name\":\"_stakeManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_penalizer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_batchGateway\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_relayRegistrar\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"maxWorkerCount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasReserve\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"postOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimumUnstakeDelay\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"devAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"devFee\",\"type\":\"uint8\"},{\"internalType\":\"uint80\",\"name\":\"baseRelayFee\",\"type\":\"uint80\"},{\"internalType\":\"uint16\",\"name\":\"pctRelayFee\",\"type\":\"uint16\"}],\"internalType\":\"struct IRelayHub.RelayHubConfig\",\"name\":\"_config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"name\":\"AbandonedRelayManagerBalanceEscheated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"deprecationTime\",\"type\":\"uint256\"}],\"name\":\"HubDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"maxWorkerCount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasReserve\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"postOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimumUnstakeDelay\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"devAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"devFee\",\"type\":\"uint8\"},{\"internalType\":\"uint80\",\"name\":\"baseRelayFee\",\"type\":\"uint80\"},{\"internalType\":\"uint16\",\"name\":\"pctRelayFee\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"struct IRelayHub.RelayHubConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"RelayHubConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"newRelayWorkers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"workersCount\",\"type\":\"uint256\"}],\"name\":\"RelayWorkersAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"minimumStake\",\"type\":\"uint256\"}],\"name\":\"StakingTokenDataChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"relayRequestID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"relayWorker\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"innerGasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TransactionRejectedByPaymaster\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayWorker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"relayRequestID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"enum IRelayHub.RelayCallStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"charge\",\"type\":\"uint256\"}],\"name\":\"TransactionRelayed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enum IRelayHub.RelayCallStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnValue\",\"type\":\"bytes\"}],\"name\":\"TransactionResult\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dest\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"newRelayWorkers\",\"type\":\"address[]\"}],\"name\":\"addRelayWorkers\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"aggregateGasleft\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transactionCalldataGasUsed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayWorker\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"clientId\",\"type\":\"uint256\"}],\"internalType\":\"struct GsnTypes.RelayData\",\"name\":\"relayData\",\"type\":\"tuple\"}],\"name\":\"calculateCharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"charge\",\"type\":\"uint256\"}],\"name\":\"calculateDevCharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"depositFor\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_deprecationTime\",\"type\":\"uint256\"}],\"name\":\"deprecateHub\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"name\":\"escheatAbandonedRelayBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBatchGateway\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfiguration\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"maxWorkerCount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasReserve\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"postOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimumUnstakeDelay\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"devAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"devFee\",\"type\":\"uint8\"},{\"internalType\":\"uint80\",\"name\":\"baseRelayFee\",\"type\":\"uint80\"},{\"internalType\":\"uint16\",\"name\":\"pctRelayFee\",\"type\":\"uint16\"}],\"internalType\":\"struct IRelayHub.RelayHubConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDeprecationTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getMinimumStakePerToken\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPenalizer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRelayRegistrar\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStakeManager\",\"outputs\":[{\"internalType\":\"contract IStakeManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"manager\",\"type\":\"address\"}],\"name\":\"getWorkerCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"worker\",\"type\":\"address\"}],\"name\":\"getWorkerManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"domainSeparatorName\",\"type\":\"string\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"validUntilTime\",\"type\":\"uint256\"}],\"internalType\":\"struct IForwarder.ForwardRequest\",\"name\":\"request\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transactionCalldataGasUsed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayWorker\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"clientId\",\"type\":\"uint256\"}],\"internalType\":\"struct GsnTypes.RelayData\",\"name\":\"relayData\",\"type\":\"tuple\"}],\"internalType\":\"struct GsnTypes.RelayRequest\",\"name\":\"relayRequest\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"approvalData\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"acceptanceBudget\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preRelayedCallGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"postRelayedCallGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"calldataSizeLimit\",\"type\":\"uint256\"}],\"internalType\":\"struct IPaymaster.GasAndDataLimits\",\"name\":\"gasAndDataLimits\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"totalInitialGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPossibleGas\",\"type\":\"uint256\"}],\"name\":\"innerRelayCall\",\"outputs\":[{\"internalType\":\"enum IRelayHub.RelayCallStatus\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"name\":\"isRelayEscheatable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"name\":\"onRelayServerRegistered\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayWorker\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"penalize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"domainSeparatorName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"maxAcceptanceBudget\",\"type\":\"uint256\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"validUntilTime\",\"type\":\"uint256\"}],\"internalType\":\"struct IForwarder.ForwardRequest\",\"name\":\"request\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transactionCalldataGasUsed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayWorker\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"clientId\",\"type\":\"uint256\"}],\"internalType\":\"struct GsnTypes.RelayData\",\"name\":\"relayData\",\"type\":\"tuple\"}],\"internalType\":\"struct GsnTypes.RelayRequest\",\"name\":\"relayRequest\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"approvalData\",\"type\":\"bytes\"}],\"name\":\"relayCall\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"paymasterAccepted\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"charge\",\"type\":\"uint256\"},{\"internalType\":\"enum IRelayHub.RelayCallStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"returnValue\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"maxWorkerCount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasReserve\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"postOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimumUnstakeDelay\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"devAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"devFee\",\"type\":\"uint8\"},{\"internalType\":\"uint80\",\"name\":\"baseRelayFee\",\"type\":\"uint80\"},{\"internalType\":\"uint16\",\"name\":\"pctRelayFee\",\"type\":\"uint16\"}],\"internalType\":\"struct IRelayHub.RelayHubConfig\",\"name\":\"_config\",\"type\":\"tuple\"}],\"name\":\"setConfiguration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20[]\",\"name\":\"token\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"minimumStake\",\"type\":\"uint256[]\"}],\"name\":\"setMinimumStakes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"name\":\"verifyRelayManagerStaked\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"versionHub\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable[]\",\"name\":\"dest\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amount\",\"type\":\"uint256[]\"}],\"name\":\"withdrawMultiple\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"aggregateGasleft()\":{\"returns\":{\"_0\":\"A total measurable amount of gas left to current execution. Same as 'gasleft()' for pure EVMs.\"}},\"balanceOf(address)\":{\"returns\":{\"_0\":\"An account's balance. It can be either a deposit of a `Paymaster`, or a revenue of a Relay Manager.\"}},\"calculateCharge(uint256,(uint256,uint256,uint256,address,address,address,bytes,uint256))\":{\"params\":{\"gasUsed\":\"An amount of gas used by the transaction.\",\"relayData\":\"The details of a transaction signed by the sender.\"},\"returns\":{\"_0\":\"The calculated charge, in wei.\"}},\"calculateDevCharge(uint256)\":{\"params\":{\"charge\":\"The amount of Ether in wei the Paymaster will be charged for this transaction.\"},\"returns\":{\"_0\":\"The calculated devFee, in wei.\"}},\"deprecateHub(uint256)\":{\"params\":{\"_deprecationTime\":\"The timestamp in seconds after which the `RelayHub` stops serving transactions.\"}},\"getBatchGateway()\":{\"returns\":{\"_0\":\"The `BatchGateway` address for this `RelayHub`.\"}},\"getConfiguration()\":{\"returns\":{\"_0\":\"The configuration of the `RelayHub`.\"}},\"getCreationBlock()\":{\"returns\":{\"_0\":\"The block number in which the contract has been deployed.\"}},\"getDeprecationTime()\":{\"returns\":{\"_0\":\"The timestamp from which the hub no longer allows relaying calls.\"}},\"getMinimumStakePerToken(address)\":{\"params\":{\"token\":\"An address of an ERC-20 compatible tokens.\"},\"returns\":{\"_0\":\"The minimum amount of a given `token` that needs to be staked so that the Relay Manager is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.\"}},\"getPenalizer()\":{\"returns\":{\"_0\":\"The `Penalizer` address for this `RelayHub`.\"}},\"getRelayRegistrar()\":{\"returns\":{\"_0\":\"The `RelayRegistrar` address for this `RelayHub`.\"}},\"getStakeManager()\":{\"returns\":{\"_0\":\"The `StakeManager` address for this `RelayHub`.\"}},\"getWorkerCount(address)\":{\"params\":{\"manager\":\"An address of the Relay Manager.\"},\"returns\":{\"_0\":\"The count of Relay Workers associated with this Relay Manager.\"}},\"getWorkerManager(address)\":{\"params\":{\"worker\":\"An address of the Relay Worker.\"},\"returns\":{\"_0\":\"The address of its Relay Manager.\"}},\"isDeprecated()\":{\"returns\":{\"_0\":\"`true` if the `RelayHub` is deprecated, `false` it it is not deprecated and can serve transactions.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"penalize(address,address)\":{\"params\":{\"beneficiary\":\"The address that called the `Penalizer` and will receive a reward for it.\",\"relayWorker\":\"The address of the Relay Worker that committed a penalizable offense.\"}},\"relayCall(string,uint256,((address,address,uint256,uint256,uint256,bytes,uint256),(uint256,uint256,uint256,address,address,address,bytes,uint256)),bytes,bytes)\":{\"params\":{\"approvalData\":\"The dapp-specific data forwarded to the `Paymaster`'s `preRelayedCall` method. This value is **not** verified by the `RelayHub` in any way. As an example, it can be used to pass some kind of a third-party signature to the `Paymaster` for verification. Emits a `TransactionRelayed` event regardless of whether the transaction succeeded or failed.\",\"domainSeparatorName\":\"The name of the Domain Separator used to verify the EIP-712 signature\",\"maxAcceptanceBudget\":\"The maximum valid value for `paymaster.getGasLimits().acceptanceBudget` to return.\",\"relayRequest\":\"All details of the requested relayed call.\",\"signature\":\"The client's EIP-712 signature over the `relayRequest` struct.\"}},\"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.\"},\"setConfiguration((uint256,uint256,uint256,uint256,uint256,address,uint8,uint80,uint16))\":{\"params\":{\"_config\":\"The new configuration.\"}},\"setMinimumStakes(address[],uint256[])\":{\"params\":{\"minimumStake\":\"An array of minimal amounts necessary for a corresponding token, in wei.\",\"token\":\"An array of addresses of ERC-20 compatible tokens.\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"versionHub()\":{\"returns\":{\"_0\":\"a SemVer-compliant version of the `RelayHub` contract.\"}}},\"title\":\"The RelayHub Implementation\",\"version\":1},\"userdoc\":{\"events\":{\"AbandonedRelayManagerBalanceEscheated(address,uint256)\":{\"notice\":\"This event is emitted in case a `relayManager` has been deemed \\\"abandoned\\\" for being unresponsive for a prolonged period of time.This event means the entire balance of the relay has been transferred to the `devAddress`.\"},\"Deposited(address,address,uint256)\":{\"notice\":\"Emitted when `depositFor` is called, including the amount and account that was funded.\"},\"HubDeprecated(uint256)\":{\"notice\":\"This event is emitted in case this `RelayHub` is deprecated and will stop serving transactions soon.\"},\"RelayHubConfigured((uint256,uint256,uint256,uint256,uint256,address,uint8,uint80,uint16))\":{\"notice\":\"Emitted when a configuration of the `RelayHub` is changed\"},\"RelayWorkersAdded(address,address[],uint256)\":{\"notice\":\"Emitted when relays are added by a relayManager\"},\"StakingTokenDataChanged(address,uint256)\":{\"notice\":\"Emitted for each token configured for staking in setMinimumStakes\"},\"TransactionRejectedByPaymaster(address,address,bytes32,address,address,address,bytes4,uint256,bytes)\":{\"notice\":\"Emitted when an attempt to relay a call fails and the `Paymaster` does not accept the transaction. The actual relayed call was not executed, and the recipient not charged.\"},\"TransactionRelayed(address,address,bytes32,address,address,address,bytes4,uint8,uint256)\":{\"notice\":\"Emitted when a transaction is relayed. Note that the actual internal function call might be reverted. The reason for a revert will be indicated in the `status` field of a corresponding `RelayCallStatus` value.`charge` is the Ether value deducted from the `Paymaster` balance. The amount added to the `relayManager` balance will be lower if there is an activated `devFee` in the `config`.\"},\"TransactionResult(uint8,bytes)\":{\"notice\":\"This event is emitted in case the internal function returns a value or reverts with a revert string.\"},\"Withdrawn(address,address,uint256)\":{\"notice\":\"Emitted when an account withdraws funds from the `RelayHub`.\"}},\"kind\":\"user\",\"methods\":{\"addRelayWorkers(address[])\":{\"notice\":\"Add new worker addresses controlled by the sender who must be a staked Relay Manager address. Emits a `RelayWorkersAdded` event. This function can be called multiple times, emitting new events.\"},\"calculateCharge(uint256,(uint256,uint256,uint256,address,address,address,bytes,uint256))\":{\"notice\":\"The fee is expressed as a base fee in wei plus percentage of the actual charge. For example, a value '40' stands for a 40% fee, so the recipient will be charged for 1.4 times the spent amount.\"},\"calculateDevCharge(uint256)\":{\"notice\":\"The fee is expressed as a percentage of the actual charge. For example, a value '40' stands for a 40% fee, so the Relay Manager will only get 60% of the `charge`.\"},\"depositFor(address)\":{\"notice\":\"Deposits ether for a `Paymaster`, so that it can and pay for relayed transactions. :warning: **Warning** :warning: Unused balance can only be withdrawn by the holder itself, by calling `withdraw`. Emits a `Deposited` event.\"},\"deprecateHub(uint256)\":{\"notice\":\"Deprecate hub by reverting all incoming `relayCall()` calls starting from a given timestamp\"},\"escheatAbandonedRelayBalance(address)\":{\"notice\":\"@param relayManager\"},\"innerRelayCall(string,((address,address,uint256,uint256,uint256,bytes,uint256),(uint256,uint256,uint256,address,address,address,bytes,uint256)),bytes,bytes,(uint256,uint256,uint256,uint256),uint256,uint256)\":{\"notice\":\"This method can only by called by this `RelayHub`. It wraps the execution of the `RelayRequest` in a revertable frame context.\"},\"isRelayEscheatable(address)\":{\"notice\":\"Uses `StakeManager` to check if the Relay Manager can be considered abandoned or not. Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\"},\"onRelayServerRegistered(address)\":{\"notice\":\"The `RelayRegistrar` callback to notify the `RelayHub` that this `relayManager` has updated registration.\"},\"penalize(address,address)\":{\"notice\":\"In case the Relay Worker has been found to be in violation of some rules by the `Penalizer` contract, the `Penalizer` will call this method to execute a penalization. The `RelayHub` will look up the Relay Manager of the given Relay Worker and will forward the call to the `StakeManager` contract. The `RelayHub` does not perform the actual penalization either.\"},\"relayCall(string,uint256,((address,address,uint256,uint256,uint256,bytes,uint256),(uint256,uint256,uint256,address,address,address,bytes,uint256)),bytes,bytes)\":{\"notice\":\"Relays a transaction. For this to succeed, multiple conditions must be met: - `Paymaster`'s `preRelayCall` method must succeed and not revert. - the `msg.sender` must be a registered Relay Worker that the user signed to use. - the transaction's gas fees must be equal or larger than the ones that were signed by the sender. - the transaction must have enough gas to run all internal transactions if they use all gas available to them. - the `Paymaster` must have enough balance to pay the Relay Worker if all gas is spent.If all conditions are met, the call will be relayed and the `Paymaster` charged.\"},\"setConfiguration((uint256,uint256,uint256,uint256,uint256,address,uint8,uint80,uint16))\":{\"notice\":\"Sets or changes the configuration of this `RelayHub`.\"},\"setMinimumStakes(address[],uint256[])\":{\"notice\":\"Sets or changes the minimum amount of a given `token` that needs to be staked so that the Relay Manager is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.\"},\"verifyRelayManagerStaked(address)\":{\"notice\":\"Uses `StakeManager` to decide if the Relay Manager can be considered staked or not. Returns if the stake's token, amount and delay satisfy all requirements, reverts otherwise.\"},\"withdraw(address,uint256)\":{\"notice\":\"Withdraws from an account's balance, sending it back to the caller. Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding. Emits a `Withdrawn` event.\"},\"withdrawMultiple(address[],uint256[])\":{\"notice\":\"Withdraws from an account's balance, sending funds to multiple provided addresses. Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding. Emits a `Withdrawn` event for each destination.\"}},\"notice\":\"This contract implements the `IRelayHub` interface for the EVM-compatible networks.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@opengsn/contracts/src/RelayHub.sol\":\"RelayHub\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@opengsn/contracts/src/RelayHub.sol\":{\"content\":\"/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable not-rely-on-time */\\n/* solhint-disable avoid-tx-origin */\\n/* solhint-disable bracket-align */\\n// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\n// #if ENABLE_CONSOLE_LOG\\nimport \\\"hardhat/console.sol\\\";\\n// #endif\\n\\nimport \\\"./utils/MinLibBytes.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nimport \\\"./utils/GsnUtils.sol\\\";\\nimport \\\"./utils/GsnEip712Library.sol\\\";\\nimport \\\"./utils/RelayHubValidator.sol\\\";\\nimport \\\"./utils/GsnTypes.sol\\\";\\nimport \\\"./interfaces/IRelayHub.sol\\\";\\nimport \\\"./interfaces/IPaymaster.sol\\\";\\nimport \\\"./forwarder/IForwarder.sol\\\";\\nimport \\\"./interfaces/IStakeManager.sol\\\";\\nimport \\\"./interfaces/IRelayRegistrar.sol\\\";\\nimport \\\"./interfaces/IStakeManager.sol\\\";\\n\\n/**\\n * @title The RelayHub Implementation\\n * @notice This contract implements the `IRelayHub` interface for the EVM-compatible networks.\\n */\\ncontract RelayHub is IRelayHub, Ownable, ERC165 {\\n using ERC165Checker for address;\\n using Address for address;\\n\\n address private constant DRY_RUN_ADDRESS = 0x0000000000000000000000000000000000000000;\\n\\n /// @inheritdoc IRelayHub\\n function versionHub() override virtual public pure returns (string memory){\\n return \\\"3.0.0-beta.3+opengsn.hub.irelayhub\\\";\\n }\\n\\n IStakeManager internal immutable stakeManager;\\n address internal immutable penalizer;\\n address internal immutable batchGateway;\\n address internal immutable relayRegistrar;\\n\\n RelayHubConfig internal config;\\n\\n /// @inheritdoc IRelayHub\\n function getConfiguration() public override view returns (RelayHubConfig memory) {\\n return config;\\n }\\n\\n /// @inheritdoc IRelayHub\\n function setConfiguration(RelayHubConfig memory _config) public override onlyOwner {\\n require(_config.devFee < 100, \\\"dev fee too high\\\");\\n config = _config;\\n emit RelayHubConfigured(config);\\n }\\n\\n // maps ERC-20 token address to a minimum stake for it\\n mapping(IERC20 => uint256) internal minimumStakePerToken;\\n\\n /// @inheritdoc IRelayHub\\n function setMinimumStakes(IERC20[] memory token, uint256[] memory minimumStake) public override onlyOwner {\\n require(token.length == minimumStake.length, \\\"setMinimumStakes: wrong length\\\");\\n for (uint256 i = 0; i < token.length; i++) {\\n minimumStakePerToken[token[i]] = minimumStake[i];\\n emit StakingTokenDataChanged(address(token[i]), minimumStake[i]);\\n }\\n }\\n\\n // maps relay worker's address to its manager's address\\n mapping(address => address) internal workerToManager;\\n\\n // maps relay managers to the number of their workers\\n mapping(address => uint256) internal workerCount;\\n\\n mapping(address => uint256) internal balances;\\n\\n uint256 internal immutable creationBlock;\\n uint256 internal deprecationTime = type(uint256).max;\\n\\n constructor (\\n IStakeManager _stakeManager,\\n address _penalizer,\\n address _batchGateway,\\n address _relayRegistrar,\\n RelayHubConfig memory _config\\n ) {\\n creationBlock = block.number;\\n stakeManager = _stakeManager;\\n penalizer = _penalizer;\\n batchGateway = _batchGateway;\\n relayRegistrar = _relayRegistrar;\\n setConfiguration(_config);\\n }\\n\\n /// @inheritdoc IRelayHub\\n function getCreationBlock() external override virtual view returns (uint256){\\n return creationBlock;\\n }\\n\\n /// @inheritdoc IRelayHub\\n function getDeprecationTime() external override view returns (uint256) {\\n return deprecationTime;\\n }\\n\\n /// @inheritdoc IRelayHub\\n function getStakeManager() external override view returns (IStakeManager) {\\n return stakeManager;\\n }\\n\\n /// @inheritdoc IRelayHub\\n function getPenalizer() external override view returns (address) {\\n return penalizer;\\n }\\n\\n /// @inheritdoc IRelayHub\\n function getBatchGateway() external override view returns (address) {\\n return batchGateway;\\n }\\n\\n /// @inheritdoc IRelayHub\\n function getRelayRegistrar() external override view returns (address) {\\n return relayRegistrar;\\n }\\n\\n /// @inheritdoc IRelayHub\\n function getMinimumStakePerToken(IERC20 token) external override view returns (uint256) {\\n return minimumStakePerToken[token];\\n }\\n\\n /// @inheritdoc IRelayHub\\n function getWorkerManager(address worker) external override view returns (address) {\\n return workerToManager[worker];\\n }\\n\\n /// @inheritdoc IRelayHub\\n function getWorkerCount(address manager) external override view returns (uint256) {\\n return workerCount[manager];\\n }\\n\\n /// @inheritdoc IERC165\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\\n return interfaceId == type(IRelayHub).interfaceId ||\\n interfaceId == type(Ownable).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /// @inheritdoc IRelayHub\\n function onRelayServerRegistered(address relayManager) external override {\\n require(msg.sender == relayRegistrar, \\\"caller is not relay registrar\\\");\\n verifyRelayManagerStaked(relayManager);\\n require(workerCount[relayManager] > 0, \\\"no relay workers\\\");\\n stakeManager.updateRelayKeepaliveTime(relayManager);\\n }\\n\\n /// @inheritdoc IRelayHub\\n function addRelayWorkers(address[] calldata newRelayWorkers) external override {\\n address relayManager = msg.sender;\\n uint256 newWorkerCount = workerCount[relayManager] + newRelayWorkers.length;\\n workerCount[relayManager] = newWorkerCount;\\n require(newWorkerCount <= config.maxWorkerCount, \\\"too many workers\\\");\\n\\n verifyRelayManagerStaked(relayManager);\\n\\n for (uint256 i = 0; i < newRelayWorkers.length; i++) {\\n require(workerToManager[newRelayWorkers[i]] == address(0), \\\"this worker has a manager\\\");\\n workerToManager[newRelayWorkers[i]] = relayManager;\\n }\\n\\n emit RelayWorkersAdded(relayManager, newRelayWorkers, newWorkerCount);\\n }\\n\\n /// @inheritdoc IRelayHub\\n function depositFor(address target) public virtual override payable {\\n require(target.supportsInterface(type(IPaymaster).interfaceId), \\\"target is not a valid IPaymaster\\\");\\n uint256 amount = msg.value;\\n\\n balances[target] = balances[target] + amount;\\n\\n emit Deposited(target, msg.sender, amount);\\n }\\n\\n /// @inheritdoc IRelayHub\\n function balanceOf(address target) external override view returns (uint256) {\\n return balances[target];\\n }\\n\\n /// @inheritdoc IRelayHub\\n function withdraw(address payable dest, uint256 amount) public override {\\n uint256[] memory amounts = new uint256[](1);\\n address payable[] memory destinations = new address payable[](1);\\n amounts[0] = amount;\\n destinations[0] = dest;\\n withdrawMultiple(destinations, amounts);\\n }\\n\\n /// @inheritdoc IRelayHub\\n function withdrawMultiple(address payable[] memory dest, uint256[] memory amount) public override {\\n address payable account = payable(msg.sender);\\n for (uint256 i = 0; i < amount.length; i++) {\\n // #if ENABLE_CONSOLE_LOG\\n console.log(\\\"withdrawMultiple %s %s %s\\\", balances[account], dest[i], amount[i]);\\n // #endif\\n uint256 balance = balances[account];\\n require(balance >= amount[i], \\\"insufficient funds\\\");\\n balances[account] = balance - amount[i];\\n (bool success, ) = dest[i].call{value: amount[i]}(\\\"\\\");\\n require(success, \\\"Transfer failed.\\\");\\n emit Withdrawn(account, dest[i], amount[i]);\\n }\\n }\\n\\n function verifyGasAndDataLimits(\\n uint256 maxAcceptanceBudget,\\n GsnTypes.RelayRequest calldata relayRequest,\\n uint256 initialGasLeft\\n )\\n private\\n view\\n returns (IPaymaster.GasAndDataLimits memory gasAndDataLimits, uint256 maxPossibleGas) {\\n gasAndDataLimits =\\n IPaymaster(relayRequest.relayData.paymaster).getGasAndDataLimits{gas:50000}();\\n require(msg.data.length <= gasAndDataLimits.calldataSizeLimit, \\\"msg.data exceeded limit\\\" );\\n\\n require(maxAcceptanceBudget >= gasAndDataLimits.acceptanceBudget, \\\"acceptance budget too high\\\");\\n require(gasAndDataLimits.acceptanceBudget >= gasAndDataLimits.preRelayedCallGasLimit, \\\"acceptance budget too low\\\");\\n\\n maxPossibleGas = relayRequest.relayData.transactionCalldataGasUsed + initialGasLeft;\\n\\n uint256 maxPossibleCharge = calculateCharge(\\n maxPossibleGas,\\n relayRequest.relayData\\n );\\n\\n // We don't yet know how much gas will be used by the recipient, so we make sure there are enough funds to pay\\n // for the maximum possible charge.\\n require(maxPossibleCharge <= balances[relayRequest.relayData.paymaster],\\n \\\"Paymaster balance too low\\\");\\n }\\n\\n struct RelayCallData {\\n bool success;\\n bytes4 functionSelector;\\n uint256 initialGasLeft;\\n bytes recipientContext;\\n bytes relayedCallReturnValue;\\n IPaymaster.GasAndDataLimits gasAndDataLimits;\\n RelayCallStatus status;\\n uint256 innerGasUsed;\\n uint256 maxPossibleGas;\\n uint256 innerGasLimit;\\n uint256 gasBeforeInner;\\n uint256 gasUsed;\\n uint256 devCharge;\\n bytes retData;\\n address relayManager;\\n bytes32 relayRequestId;\\n uint256 tmpInitialGas;\\n bytes relayCallStatus;\\n }\\n\\n /// @inheritdoc IRelayHub\\n function relayCall(\\n string calldata domainSeparatorName,\\n uint256 maxAcceptanceBudget,\\n GsnTypes.RelayRequest calldata relayRequest,\\n bytes calldata signature,\\n bytes calldata approvalData\\n )\\n external\\n override\\n returns (\\n bool paymasterAccepted,\\n uint256 charge,\\n IRelayHub.RelayCallStatus status,\\n bytes memory returnValue)\\n {\\n RelayCallData memory vars;\\n vars.initialGasLeft = aggregateGasleft();\\n vars.relayRequestId = GsnUtils.getRelayRequestID(relayRequest, signature);\\n\\n // #if ENABLE_CONSOLE_LOG\\n console.log(\\\"relayCall relayRequestId\\\");\\n console.logBytes32(vars.relayRequestId);\\n console.log(\\\"relayCall relayRequest.request.from\\\", relayRequest.request.from);\\n console.log(\\\"relayCall relayRequest.request.to\\\", relayRequest.request.to);\\n console.log(\\\"relayCall relayRequest.request.value\\\", relayRequest.request.value);\\n console.log(\\\"relayCall relayRequest.request.gas\\\", relayRequest.request.gas);\\n console.log(\\\"relayCall relayRequest.request.nonce\\\", relayRequest.request.nonce);\\n console.log(\\\"relayCall relayRequest.request.validUntilTime\\\", relayRequest.request.validUntilTime);\\n\\n console.log(\\\"relayCall relayRequest.relayData.maxFeePerGas\\\", relayRequest.relayData.maxFeePerGas);\\n console.log(\\\"relayCall relayRequest.relayData.maxPriorityFeePerGas\\\", relayRequest.relayData.maxPriorityFeePerGas);\\n console.log(\\\"relayCall relayRequest.relayData.transactionCalldataGasUsed\\\", relayRequest.relayData.transactionCalldataGasUsed);\\n console.log(\\\"relayCall relayRequest.relayData.relayWorker\\\", relayRequest.relayData.relayWorker);\\n console.log(\\\"relayCall relayRequest.relayData.paymaster\\\", relayRequest.relayData.paymaster);\\n console.log(\\\"relayCall relayRequest.relayData.forwarder\\\", relayRequest.relayData.forwarder);\\n console.log(\\\"relayCall relayRequest.relayData.clientId\\\", relayRequest.relayData.clientId);\\n\\n console.log(\\\"relayCall domainSeparatorName\\\");\\n console.logString(domainSeparatorName);\\n console.log(\\\"relayCall signature\\\");\\n console.logBytes(signature);\\n console.log(\\\"relayCall approvalData\\\");\\n console.logBytes(approvalData);\\n console.log(\\\"relayCall relayRequest.request.data\\\");\\n console.logBytes(relayRequest.request.data);\\n console.log(\\\"relayCall relayRequest.relayData.paymasterData\\\");\\n console.logBytes(relayRequest.relayData.paymasterData);\\n console.log(\\\"relayCall maxAcceptanceBudget\\\", maxAcceptanceBudget);\\n // #endif\\n\\n require(!isDeprecated(), \\\"hub deprecated\\\");\\n vars.functionSelector = relayRequest.request.data.length>=4 ? MinLibBytes.readBytes4(relayRequest.request.data, 0) : bytes4(0);\\n\\n if (msg.sender != batchGateway && tx.origin != DRY_RUN_ADDRESS) {\\n require(signature.length != 0, \\\"missing signature or bad gateway\\\");\\n require(msg.sender == tx.origin, \\\"relay worker must be EOA\\\");\\n require(msg.sender == relayRequest.relayData.relayWorker, \\\"Not a right worker\\\");\\n }\\n\\n if (tx.origin != DRY_RUN_ADDRESS) {\\n vars.relayManager = workerToManager[relayRequest.relayData.relayWorker];\\n require(vars.relayManager != address(0), \\\"Unknown relay worker\\\");\\n verifyRelayManagerStaked(vars.relayManager);\\n }\\n\\n (vars.gasAndDataLimits, vars.maxPossibleGas) =\\n verifyGasAndDataLimits(maxAcceptanceBudget, relayRequest, vars.initialGasLeft);\\n\\n RelayHubValidator.verifyTransactionPacking(domainSeparatorName,relayRequest,signature,approvalData);\\n\\n {\\n\\n //How much gas to pass down to innerRelayCall. must be lower than the default 63/64\\n // actually, min(gasleft*63/64, gasleft-GAS_RESERVE) might be enough.\\n vars.innerGasLimit = gasleft()*63/64- config.gasReserve;\\n vars.gasBeforeInner = aggregateGasleft();\\n\\n /*\\n Preparing to calculate \\\"gasUseWithoutPost\\\":\\n MPG = calldataGasUsage + vars.initialGasLeft :: max possible gas, an approximate gas limit for the current transaction\\n GU1 = MPG - gasleft(called right before innerRelayCall) :: gas actually used by current transaction until that point\\n GU2 = innerGasLimit - gasleft(called inside the innerRelayCall just before preRelayedCall) :: gas actually used by innerRelayCall before calling postRelayCall\\n GWP1 = GU1 + GU2 :: gas actually used by the entire transaction before calling postRelayCall\\n TGO = config.gasOverhead + config.postOverhead :: extra that will be added to the charge to cover hidden costs\\n GWP = GWP1 + TGO :: transaction \\\"gas used without postRelayCall\\\"\\n */\\n vars.tmpInitialGas = relayRequest.relayData.transactionCalldataGasUsed + vars.initialGasLeft + vars.innerGasLimit + config.gasOverhead + config.postOverhead;\\n // Calls to the recipient are performed atomically inside an inner transaction which may revert in case of\\n // errors in the recipient. In either case (revert or regular execution) the return data encodes the\\n // RelayCallStatus value.\\n (vars.success, vars.relayCallStatus) = address(this).call{gas:vars.innerGasLimit}(\\n abi.encodeWithSelector(RelayHub.innerRelayCall.selector, domainSeparatorName, relayRequest, signature, approvalData, vars.gasAndDataLimits,\\n vars.tmpInitialGas - aggregateGasleft(), /* totalInitialGas */\\n vars.maxPossibleGas\\n )\\n );\\n vars.innerGasUsed = vars.gasBeforeInner-aggregateGasleft();\\n (vars.status, vars.relayedCallReturnValue) = abi.decode(vars.relayCallStatus, (RelayCallStatus, bytes));\\n if ( vars.relayedCallReturnValue.length>0 ) {\\n emit TransactionResult(vars.status, vars.relayedCallReturnValue);\\n }\\n }\\n {\\n if (!vars.success) {\\n //Failure cases where the PM doesn't pay\\n if (vars.status == RelayCallStatus.RejectedByPreRelayed ||\\n (vars.innerGasUsed <= vars.gasAndDataLimits.acceptanceBudget + relayRequest.relayData.transactionCalldataGasUsed) && (\\n vars.status == RelayCallStatus.RejectedByForwarder ||\\n vars.status == RelayCallStatus.RejectedByRecipientRevert //can only be thrown if rejectOnRecipientRevert==true\\n )) {\\n emit TransactionRejectedByPaymaster(\\n vars.relayManager,\\n relayRequest.relayData.paymaster,\\n vars.relayRequestId,\\n relayRequest.request.from,\\n relayRequest.request.to,\\n msg.sender,\\n vars.functionSelector,\\n vars.innerGasUsed,\\n vars.relayedCallReturnValue);\\n return (false, 0, vars.status, vars.relayedCallReturnValue);\\n }\\n }\\n\\n // We now perform the actual charge calculation, based on the measured gas used\\n vars.gasUsed = relayRequest.relayData.transactionCalldataGasUsed + (vars.initialGasLeft - aggregateGasleft()) + config.gasOverhead;\\n charge = calculateCharge(vars.gasUsed, relayRequest.relayData);\\n vars.devCharge = calculateDevCharge(charge);\\n\\n balances[relayRequest.relayData.paymaster] = balances[relayRequest.relayData.paymaster] - charge;\\n balances[vars.relayManager] = balances[vars.relayManager] + (charge - vars.devCharge);\\n if (vars.devCharge > 0) { // save some gas in case of zero dev charge\\n balances[config.devAddress] = balances[config.devAddress] + vars.devCharge;\\n }\\n\\n {\\n address from = relayRequest.request.from;\\n address to = relayRequest.request.to;\\n address paymaster = relayRequest.relayData.paymaster;\\n emit TransactionRelayed(\\n vars.relayManager,\\n msg.sender,\\n vars.relayRequestId,\\n from,\\n to,\\n paymaster,\\n vars.functionSelector,\\n vars.status,\\n charge);\\n }\\n\\n // avoid variable size memory copying after gas calculation completed on-chain\\n if (tx.origin == DRY_RUN_ADDRESS) {\\n return (true, charge, vars.status, vars.relayedCallReturnValue);\\n }\\n return (true, charge, vars.status, \\\"\\\");\\n }\\n }\\n\\n struct InnerRelayCallData {\\n uint256 initialGasLeft;\\n uint256 gasUsedToCallInner;\\n uint256 balanceBefore;\\n bytes32 preReturnValue;\\n bool relayedCallSuccess;\\n bytes relayedCallReturnValue;\\n bytes recipientContext;\\n bytes data;\\n bool rejectOnRecipientRevert;\\n }\\n\\n /**\\n * @notice This method can only by called by this `RelayHub`.\\n * It wraps the execution of the `RelayRequest` in a revertable frame context.\\n */\\n function innerRelayCall(\\n string calldata domainSeparatorName,\\n GsnTypes.RelayRequest calldata relayRequest,\\n bytes calldata signature,\\n bytes calldata approvalData,\\n IPaymaster.GasAndDataLimits calldata gasAndDataLimits,\\n uint256 totalInitialGas,\\n uint256 maxPossibleGas\\n )\\n external\\n returns (RelayCallStatus, bytes memory)\\n {\\n InnerRelayCallData memory vars;\\n vars.initialGasLeft = aggregateGasleft();\\n vars.gasUsedToCallInner = totalInitialGas - gasleft();\\n // A new gas measurement is performed inside innerRelayCall, since\\n // due to EIP150 available gas amounts cannot be directly compared across external calls\\n\\n // This external function can only be called by RelayHub itself, creating an internal transaction. Calls to the\\n // recipient (preRelayedCall, the relayedCall, and postRelayedCall) are called from inside this transaction.\\n require(msg.sender == address(this), \\\"Must be called by RelayHub\\\");\\n\\n // If either pre or post reverts, the whole internal transaction will be reverted, reverting all side effects on\\n // the recipient. The recipient will still be charged for the used gas by the relay.\\n\\n // The paymaster is no allowed to withdraw balance from RelayHub during a relayed transaction. We check pre and\\n // post state to ensure this doesn't happen.\\n vars.balanceBefore = balances[relayRequest.relayData.paymaster];\\n\\n // First preRelayedCall is executed.\\n // Note: we open a new block to avoid growing the stack too much.\\n vars.data = abi.encodeWithSelector(\\n IPaymaster.preRelayedCall.selector,\\n relayRequest, signature, approvalData, maxPossibleGas\\n );\\n {\\n bool success;\\n bytes memory retData;\\n (success, retData) = relayRequest.relayData.paymaster.call{gas:gasAndDataLimits.preRelayedCallGasLimit}(vars.data);\\n if (!success) {\\n GsnEip712Library.truncateInPlace(retData);\\n revertWithStatus(RelayCallStatus.RejectedByPreRelayed, retData);\\n }\\n (vars.recipientContext, vars.rejectOnRecipientRevert) = abi.decode(retData, (bytes,bool));\\n }\\n\\n // The actual relayed call is now executed. The sender's address is appended at the end of the transaction data\\n\\n {\\n bool forwarderSuccess;\\n (forwarderSuccess, vars.relayedCallSuccess, vars.relayedCallReturnValue) = GsnEip712Library.execute(domainSeparatorName, relayRequest, signature);\\n if ( !forwarderSuccess ) {\\n revertWithStatus(RelayCallStatus.RejectedByForwarder, vars.relayedCallReturnValue);\\n }\\n\\n if (vars.rejectOnRecipientRevert && !vars.relayedCallSuccess) {\\n // we trusted the recipient, but it reverted...\\n revertWithStatus(RelayCallStatus.RejectedByRecipientRevert, vars.relayedCallReturnValue);\\n }\\n }\\n // Finally, postRelayedCall is executed, with the relayedCall execution's status and a charge estimate\\n // We now determine how much the recipient will be charged, to pass this value to postRelayedCall for accurate\\n // accounting.\\n vars.data = abi.encodeWithSelector(\\n IPaymaster.postRelayedCall.selector,\\n vars.recipientContext,\\n vars.relayedCallSuccess,\\n vars.gasUsedToCallInner + (vars.initialGasLeft - aggregateGasleft()), /*gasUseWithoutPost*/\\n relayRequest.relayData\\n );\\n\\n {\\n (bool successPost,bytes memory ret) = relayRequest.relayData.paymaster.call{gas:gasAndDataLimits.postRelayedCallGasLimit}(vars.data);\\n\\n if (!successPost) {\\n revertWithStatus(RelayCallStatus.PostRelayedFailed, ret);\\n }\\n }\\n\\n if (balances[relayRequest.relayData.paymaster] < vars.balanceBefore) {\\n revertWithStatus(RelayCallStatus.PaymasterBalanceChanged, \\\"\\\");\\n }\\n\\n return (vars.relayedCallSuccess ? RelayCallStatus.OK : RelayCallStatus.RelayedCallFailed, vars.relayedCallReturnValue);\\n }\\n\\n /**\\n * @dev Reverts the transaction with return data set to the ABI encoding of the status argument (and revert reason data)\\n */\\n function revertWithStatus(RelayCallStatus status, bytes memory ret) private pure {\\n bytes memory data = abi.encode(status, ret);\\n GsnEip712Library.truncateInPlace(data);\\n\\n assembly {\\n let dataSize := mload(data)\\n let dataPtr := add(data, 32)\\n\\n revert(dataPtr, dataSize)\\n }\\n }\\n\\n /// @inheritdoc IRelayHub\\n function calculateDevCharge(uint256 charge) public override virtual view returns (uint256){\\n if (config.devFee == 0){ // save some gas in case of zero dev charge\\n return 0;\\n }\\n unchecked {\\n return charge * config.devFee / 100;\\n }\\n }\\n\\n /// @inheritdoc IRelayHub\\n function calculateCharge(uint256 gasUsed, GsnTypes.RelayData calldata relayData) public override virtual view returns (uint256) {\\n uint256 basefee;\\n if (relayData.maxFeePerGas == relayData.maxPriorityFeePerGas) {\\n basefee = 0;\\n } else {\\n basefee = block.basefee;\\n }\\n uint256 chargeableGasPrice = Math.min(relayData.maxFeePerGas, Math.min(tx.gasprice, basefee + relayData.maxPriorityFeePerGas));\\n return config.baseRelayFee + (gasUsed * chargeableGasPrice * (config.pctRelayFee + 100)) / 100;\\n }\\n\\n /// @inheritdoc IRelayHub\\n function verifyRelayManagerStaked(address relayManager) public override view {\\n (IStakeManager.StakeInfo memory info, bool isHubAuthorized) = stakeManager.getStakeInfo(relayManager);\\n uint256 minimumStake = minimumStakePerToken[info.token];\\n require(info.token != IERC20(address(0)), \\\"relay manager not staked\\\");\\n require(info.stake >= minimumStake, \\\"stake amount is too small\\\");\\n require(minimumStake != 0, \\\"staking this token is forbidden\\\");\\n require(info.unstakeDelay >= config.minimumUnstakeDelay, \\\"unstake delay is too small\\\");\\n require(info.withdrawTime == 0, \\\"stake has been withdrawn\\\");\\n require(isHubAuthorized, \\\"this hub is not authorized by SM\\\");\\n }\\n\\n /// @inheritdoc IRelayHub\\n function deprecateHub(uint256 _deprecationTime) public override onlyOwner {\\n require(!isDeprecated(), \\\"Already deprecated\\\");\\n deprecationTime = _deprecationTime;\\n emit HubDeprecated(deprecationTime);\\n }\\n\\n /// @inheritdoc IRelayHub\\n function isDeprecated() public override view returns (bool) {\\n return block.timestamp >= deprecationTime;\\n }\\n\\n /// @notice Prevents any address other than the `Penalizer` from calling this method.\\n modifier penalizerOnly () {\\n require(msg.sender == penalizer, \\\"Not penalizer\\\");\\n _;\\n }\\n\\n /// @inheritdoc IRelayHub\\n function penalize(address relayWorker, address payable beneficiary) external override penalizerOnly {\\n address relayManager = workerToManager[relayWorker];\\n // The worker must be controlled by a manager with a locked stake\\n require(relayManager != address(0), \\\"Unknown relay worker\\\");\\n (IStakeManager.StakeInfo memory stakeInfo,) = stakeManager.getStakeInfo(relayManager);\\n require(stakeInfo.stake > 0, \\\"relay manager not staked\\\");\\n stakeManager.penalizeRelayManager(relayManager, beneficiary, stakeInfo.stake);\\n }\\n\\n /// @inheritdoc IRelayHub\\n function isRelayEscheatable(address relayManager) public view override returns (bool){\\n return stakeManager.isRelayEscheatable(relayManager);\\n }\\n\\n /// @inheritdoc IRelayHub\\n function escheatAbandonedRelayBalance(address relayManager) external override onlyOwner {\\n require(stakeManager.isRelayEscheatable(relayManager), \\\"relay server not escheatable yet\\\");\\n uint256 balance = balances[relayManager];\\n balances[relayManager] = 0;\\n balances[config.devAddress] = balances[config.devAddress] + balance;\\n emit AbandonedRelayManagerBalanceEscheated(relayManager, balance);\\n }\\n\\n /// @inheritdoc IRelayHub\\n function aggregateGasleft() public override virtual view returns (uint256){\\n return gasleft();\\n }\\n}\\n\",\"keccak256\":\"0x2e619558f086222a56756df872f3618bc0ee55e79b7fe9f3217d4a0a2f4aa679\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/forwarder/IForwarder.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\n\\n/**\\n * @title The Forwarder Interface\\n * @notice The contracts implementing this interface take a role of authorization, authentication and replay protection\\n * for contracts that choose to trust a `Forwarder`, instead of relying on a mechanism built into the Ethereum protocol.\\n *\\n * @notice if the `Forwarder` contract decides that an incoming `ForwardRequest` is valid, it must append 20 bytes that\\n * represent the caller to the `data` field of the request and send this new data to the target address (the `to` field)\\n *\\n * :warning: **Warning** :warning: The Forwarder can have a full control over a `Recipient` contract.\\n * Any vulnerability in a `Forwarder` implementation can make all of its `Recipient` contracts susceptible!\\n * Recipient contracts should only trust forwarders that passed through security audit,\\n * otherwise they are susceptible to identity theft.\\n */\\ninterface IForwarder is IERC165 {\\n\\n /**\\n * @notice A representation of a request for a `Forwarder` to send `data` on behalf of a `from` to a target (`to`).\\n */\\n struct ForwardRequest {\\n address from;\\n address to;\\n uint256 value;\\n uint256 gas;\\n uint256 nonce;\\n bytes data;\\n uint256 validUntilTime;\\n }\\n\\n event DomainRegistered(bytes32 indexed domainSeparator, bytes domainValue);\\n\\n event RequestTypeRegistered(bytes32 indexed typeHash, string typeStr);\\n\\n /**\\n * @param from The address of a sender.\\n * @return The nonce for this address.\\n */\\n function getNonce(address from)\\n external view\\n returns(uint256);\\n\\n /**\\n * @notice Verify the transaction is valid and can be executed.\\n * Implementations must validate the signature and the nonce of the request are correct.\\n * Does not revert and returns successfully if the input is valid.\\n * Reverts if any validation has failed. For instance, if either signature or nonce are incorrect.\\n * Reverts if `domainSeparator` or `requestTypeHash` are not registered as well.\\n */\\n function verify(\\n ForwardRequest calldata forwardRequest,\\n bytes32 domainSeparator,\\n bytes32 requestTypeHash,\\n bytes calldata suffixData,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * @notice Executes a transaction specified by the `ForwardRequest`.\\n * The transaction is first verified and then executed.\\n * The success flag and returned bytes array of the `CALL` are returned as-is.\\n *\\n * This method would revert only in case of a verification error.\\n *\\n * All the target errors are reported using the returned success flag and returned bytes array.\\n *\\n * @param forwardRequest All requested transaction parameters.\\n * @param domainSeparator The domain used when signing this request.\\n * @param requestTypeHash The request type used when signing this request.\\n * @param suffixData The ABI-encoded extension data for the current `RequestType` used when signing this request.\\n * @param signature The client signature to be validated.\\n *\\n * @return success The success flag of the underlying `CALL` to the target address.\\n * @return ret The byte array returned by the underlying `CALL` to the target address.\\n */\\n function execute(\\n ForwardRequest calldata forwardRequest,\\n bytes32 domainSeparator,\\n bytes32 requestTypeHash,\\n bytes calldata suffixData,\\n bytes calldata signature\\n )\\n external payable\\n returns (bool success, bytes memory ret);\\n\\n /**\\n * @notice Register a new Request typehash.\\n *\\n * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\\n *\\n * @param typeName The name of the request type.\\n * @param typeSuffix Any extra data after the generic params. Must contain add at least one param.\\n * The generic ForwardRequest type is always registered by the constructor.\\n */\\n function registerRequestType(string calldata typeName, string calldata typeSuffix) external;\\n\\n /**\\n * @notice Register a new domain separator.\\n *\\n * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\\n *\\n * @notice The domain separator must have the following fields: `name`, `version`, `chainId`, `verifyingContract`.\\n * The `chainId` is the current network's `chainId`, and the `verifyingContract` is this Forwarder's address.\\n * This method accepts the domain name and version to create and register the domain separator value.\\n * @param name The domain's display name.\\n * @param version The domain/protocol version.\\n */\\n function registerDomainSeparator(string calldata name, string calldata version) external;\\n}\\n\",\"keccak256\":\"0x28669953bd3dcc98a5f959fa3cac97444584b6fbe59341681b9a59f11a83b171\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/interfaces/IERC2771Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title The ERC-2771 Recipient Base Abstract Class - Declarations\\n *\\n * @notice A contract must implement this interface in order to support relayed transaction.\\n *\\n * @notice It is recommended that your contract inherits from the ERC2771Recipient contract.\\n */\\nabstract contract IERC2771Recipient {\\n\\n /**\\n * :warning: **Warning** :warning: The Forwarder can have a full control over your Recipient. Only trust verified Forwarder.\\n * @param forwarder The address of the Forwarder contract that is being used.\\n * @return isTrustedForwarder `true` if the Forwarder is trusted to forward relayed transactions by this Recipient.\\n */\\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\\n\\n /**\\n * @notice Use this method the contract anywhere instead of msg.sender to support relayed transactions.\\n * @return sender The real sender of this call.\\n * For a call that came through the Forwarder the real sender is extracted from the last 20 bytes of the `msg.data`.\\n * Otherwise simply returns `msg.sender`.\\n */\\n function _msgSender() internal virtual view returns (address);\\n\\n /**\\n * @notice Use this method in the contract instead of `msg.data` when difference matters (hashing, signature, etc.)\\n * @return data The real `msg.data` of this call.\\n * For a call that came through the Forwarder, the real sender address was appended as the last 20 bytes\\n * of the `msg.data` - so this method will strip those 20 bytes off.\\n * Otherwise (if the call was made directly and not through the forwarder) simply returns `msg.data`.\\n */\\n function _msgData() internal virtual view returns (bytes calldata);\\n}\\n\",\"keccak256\":\"0xc762358681e3494519a5fff2f7e3f0f74f9c9f395f23b00cdfb45e0fb9ef8170\",\"license\":\"MIT\"},\"@opengsn/contracts/src/interfaces/IPaymaster.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\n\\nimport \\\"../utils/GsnTypes.sol\\\";\\n\\n/**\\n * @title The Paymaster Interface\\n * @notice Contracts implementing this interface exist to make decision about paying the transaction fee to the relay.\\n *\\n * @notice There are two callbacks here that are executed by the RelayHub: `preRelayedCall` and `postRelayedCall`.\\n *\\n * @notice It is recommended that your implementation inherits from the abstract BasePaymaster contract.\\n*/\\ninterface IPaymaster is IERC165 {\\n /**\\n * @notice The limits this Paymaster wants to be imposed by the RelayHub on user input. See `getGasAndDataLimits`.\\n */\\n struct GasAndDataLimits {\\n uint256 acceptanceBudget;\\n uint256 preRelayedCallGasLimit;\\n uint256 postRelayedCallGasLimit;\\n uint256 calldataSizeLimit;\\n }\\n\\n /**\\n * @notice Return the Gas Limits for Paymaster's functions and maximum msg.data length values for this Paymaster.\\n * This function allows different paymasters to have different properties without changes to the RelayHub.\\n * @return limits An instance of the `GasAndDataLimits` struct\\n *\\n * ##### `acceptanceBudget`\\n * If the transactions consumes more than `acceptanceBudget` this Paymaster will be charged for gas no matter what.\\n * Transaction that gets rejected after consuming more than `acceptanceBudget` gas is on this Paymaster's expense.\\n *\\n * Should be set to an amount gas this Paymaster expects to spend deciding whether to accept or reject a request.\\n * This includes gas consumed by calculations in the `preRelayedCall`, `Forwarder` and the recipient contract.\\n *\\n * :warning: **Warning** :warning: As long this value is above `preRelayedCallGasLimit`\\n * (see defaults in `BasePaymaster`), the Paymaster is guaranteed it will never pay for rejected transactions.\\n * If this value is below `preRelayedCallGasLimit`, it might might make Paymaster open to a \\\"griefing\\\" attack.\\n *\\n * The relayers should prefer lower `acceptanceBudget`, as it improves their chances of being compensated.\\n * From a Relay's point of view, this is the highest gas value a bad Paymaster may cost the relay,\\n * since the paymaster will pay anything above that value regardless of whether the transaction succeeds or reverts.\\n * Specifying value too high might make the call rejected by relayers (see `maxAcceptanceBudget` in server config).\\n *\\n * ##### `preRelayedCallGasLimit`\\n * The max gas usage of preRelayedCall. Any revert of the `preRelayedCall` is a request rejection by the paymaster.\\n * As long as `acceptanceBudget` is above `preRelayedCallGasLimit`, any such revert is not payed by the paymaster.\\n *\\n * ##### `postRelayedCallGasLimit`\\n * The max gas usage of postRelayedCall. The Paymaster is not charged for the maximum, only for actually used gas.\\n * Note that an OOG will revert the inner transaction, but the paymaster will be charged for it anyway.\\n */\\n function getGasAndDataLimits()\\n external\\n view\\n returns (\\n GasAndDataLimits memory limits\\n );\\n\\n /**\\n * @notice :warning: **Warning** :warning: using incorrect Forwarder may cause the Paymaster to agreeing to pay for invalid transactions.\\n * @return trustedForwarder The address of the `Forwarder` that is trusted by this Paymaster to execute the requests.\\n */\\n function getTrustedForwarder() external view returns (address trustedForwarder);\\n\\n /**\\n * @return relayHub The address of the `RelayHub` that is trusted by this Paymaster to execute the requests.\\n */\\n function getRelayHub() external view returns (address relayHub);\\n\\n /**\\n * @notice Called by the Relay in view mode and later by the `RelayHub` on-chain to validate that\\n * the Paymaster agrees to pay for this call.\\n *\\n * The request is considered to be rejected by the Paymaster in one of the following conditions:\\n * - `preRelayedCall()` method reverts\\n * - the `Forwarder` reverts because of nonce or signature error\\n * - the `Paymaster` returned `rejectOnRecipientRevert: true` and the recipient contract reverted\\n * (and all that did not consume more than `acceptanceBudget` gas).\\n *\\n * In any of the above cases, all Paymaster calls and the recipient call are reverted.\\n * In any other case the Paymaster will pay for the gas cost of the transaction.\\n * Note that even if `postRelayedCall` is reverted the Paymaster will be charged.\\n *\\n\\n * @param relayRequest - the full relay request structure\\n * @param signature - user's EIP712-compatible signature of the `relayRequest`.\\n * Note that in most cases the paymaster shouldn't try use it at all. It is always checked\\n * by the forwarder immediately after preRelayedCall returns.\\n * @param approvalData - extra dapp-specific data (e.g. signature from trusted party)\\n * @param maxPossibleGas - based on values returned from `getGasAndDataLimits`\\n * the RelayHub will calculate the maximum possible amount of gas the user may be charged for.\\n * In order to convert this value to wei, the Paymaster has to call \\\"relayHub.calculateCharge()\\\"\\n *\\n * @return context\\n * A byte array to be passed to postRelayedCall.\\n * Can contain any data needed by this Paymaster in any form or be empty if no extra data is needed.\\n * @return rejectOnRecipientRevert\\n * The flag that allows a Paymaster to \\\"delegate\\\" the rejection to the recipient code.\\n * It also means the Paymaster trust the recipient to reject fast: both preRelayedCall,\\n * forwarder check and recipient checks must fit into the GasLimits.acceptanceBudget,\\n * otherwise the TX is paid by the Paymaster.\\n * `true` if the Paymaster wants to reject the TX if the recipient reverts.\\n * `false` if the Paymaster wants rejects by the recipient to be completed on chain and paid by the Paymaster.\\n */\\n function preRelayedCall(\\n GsnTypes.RelayRequest calldata relayRequest,\\n bytes calldata signature,\\n bytes calldata approvalData,\\n uint256 maxPossibleGas\\n )\\n external\\n returns (bytes memory context, bool rejectOnRecipientRevert);\\n\\n /**\\n * @notice This method is called after the actual relayed function call.\\n * It may be used to record the transaction (e.g. charge the caller by some contract logic) for this call.\\n *\\n * Revert in this functions causes a revert of the client's relayed call (and preRelayedCall(), but the Paymaster\\n * is still committed to pay the relay for the entire transaction.\\n *\\n * @param context The call context, as returned by the preRelayedCall\\n * @param success `true` if the relayed call succeeded, false if it reverted\\n * @param gasUseWithoutPost The actual amount of gas used by the entire transaction, EXCEPT\\n * the gas used by the postRelayedCall itself.\\n * @param relayData The relay params of the request. can be used by relayHub.calculateCharge()\\n *\\n */\\n function postRelayedCall(\\n bytes calldata context,\\n bool success,\\n uint256 gasUseWithoutPost,\\n GsnTypes.RelayData calldata relayData\\n ) external;\\n\\n /**\\n * @return version The SemVer string of this Paymaster's version.\\n */\\n function versionPaymaster() external view returns (string memory);\\n}\\n\",\"keccak256\":\"0xeedb6d83ce600a97a4abbb614d24c65cb2ebc06a1784cc6a81afa9233d1331b6\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/interfaces/IRelayHub.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\n\\nimport \\\"../utils/GsnTypes.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\n\\n/**\\n * @title The RelayHub interface\\n * @notice The implementation of this interface provides all the information the GSN client needs to\\n * create a valid `RelayRequest` and also serves as an entry point for such requests.\\n *\\n * @notice The RelayHub also handles all the related financial records and hold the balances of participants.\\n * The Paymasters keep their Ether deposited in the `RelayHub` in order to pay for the `RelayRequest`s that thay choose\\n * to pay for, and Relay Servers keep their earned Ether in the `RelayHub` until they choose to `withdraw()`\\n *\\n * @notice The RelayHub on each supported network only needs a single instance and there is usually no need for dApp\\n * developers or Relay Server operators to redeploy, reimplement, modify or override the `RelayHub`.\\n */\\ninterface IRelayHub is IERC165 {\\n /**\\n * @notice A struct that contains all the parameters of the `RelayHub` that can be modified after the deployment.\\n */\\n struct RelayHubConfig {\\n // maximum number of worker accounts allowed per manager\\n uint256 maxWorkerCount;\\n // Gas set aside for all relayCall() instructions to prevent unexpected out-of-gas exceptions\\n uint256 gasReserve;\\n // Gas overhead to calculate gasUseWithoutPost\\n uint256 postOverhead;\\n // Gas cost of all relayCall() instructions after actual 'calculateCharge()'\\n // Assume that relay has non-zero balance (costs 15'000 more otherwise).\\n uint256 gasOverhead;\\n // Minimum unstake delay seconds of a relay manager's stake on the StakeManager\\n uint256 minimumUnstakeDelay;\\n // Developers address\\n address devAddress;\\n // 0 < fee < 100, as percentage of total charge from paymaster to relayer\\n uint8 devFee;\\n // baseRelayFee The base fee the Relay Server charges for a single transaction in Ether, in wei.\\n uint80 baseRelayFee;\\n // pctRelayFee The percent of the total charge to add as a Relay Server fee to the total charge.\\n uint16 pctRelayFee;\\n }\\n\\n /// @notice Emitted when a configuration of the `RelayHub` is changed\\n event RelayHubConfigured(RelayHubConfig config);\\n\\n /// @notice Emitted when relays are added by a relayManager\\n event RelayWorkersAdded(\\n address indexed relayManager,\\n address[] newRelayWorkers,\\n uint256 workersCount\\n );\\n\\n /// @notice Emitted when an account withdraws funds from the `RelayHub`.\\n event Withdrawn(\\n address indexed account,\\n address indexed dest,\\n uint256 amount\\n );\\n\\n /// @notice Emitted when `depositFor` is called, including the amount and account that was funded.\\n event Deposited(\\n address indexed paymaster,\\n address indexed from,\\n uint256 amount\\n );\\n\\n /// @notice Emitted for each token configured for staking in setMinimumStakes\\n event StakingTokenDataChanged(\\n address token,\\n uint256 minimumStake\\n );\\n\\n /**\\n * @notice Emitted when an attempt to relay a call fails and the `Paymaster` does not accept the transaction.\\n * The actual relayed call was not executed, and the recipient not charged.\\n * @param reason contains a revert reason returned from preRelayedCall or forwarder.\\n */\\n event TransactionRejectedByPaymaster(\\n address indexed relayManager,\\n address indexed paymaster,\\n bytes32 indexed relayRequestID,\\n address from,\\n address to,\\n address relayWorker,\\n bytes4 selector,\\n uint256 innerGasUsed,\\n bytes reason\\n );\\n\\n /**\\n * @notice Emitted when a transaction is relayed. Note that the actual internal function call might be reverted.\\n * The reason for a revert will be indicated in the `status` field of a corresponding `RelayCallStatus` value.\\n * @notice `charge` is the Ether value deducted from the `Paymaster` balance.\\n * The amount added to the `relayManager` balance will be lower if there is an activated `devFee` in the `config`.\\n */\\n event TransactionRelayed(\\n address indexed relayManager,\\n address indexed relayWorker,\\n bytes32 indexed relayRequestID,\\n address from,\\n address to,\\n address paymaster,\\n bytes4 selector,\\n RelayCallStatus status,\\n uint256 charge\\n );\\n\\n /// @notice This event is emitted in case the internal function returns a value or reverts with a revert string.\\n event TransactionResult(\\n RelayCallStatus status,\\n bytes returnValue\\n );\\n\\n /// @notice This event is emitted in case this `RelayHub` is deprecated and will stop serving transactions soon.\\n event HubDeprecated(uint256 deprecationTime);\\n\\n /**\\n * @notice This event is emitted in case a `relayManager` has been deemed \\\"abandoned\\\" for being\\n * unresponsive for a prolonged period of time.\\n * @notice This event means the entire balance of the relay has been transferred to the `devAddress`.\\n */\\n event AbandonedRelayManagerBalanceEscheated(\\n address indexed relayManager,\\n uint256 balance\\n );\\n\\n /**\\n * Error codes that describe all possible failure reasons reported in the `TransactionRelayed` event `status` field.\\n * @param OK The transaction was successfully relayed and execution successful - never included in the event.\\n * @param RelayedCallFailed The transaction was relayed, but the relayed call failed.\\n * @param RejectedByPreRelayed The transaction was not relayed due to preRelatedCall reverting.\\n * @param RejectedByForwarder The transaction was not relayed due to forwarder check (signature,nonce).\\n * @param PostRelayedFailed The transaction was relayed and reverted due to postRelatedCall reverting.\\n * @param PaymasterBalanceChanged The transaction was relayed and reverted due to the paymaster balance change.\\n */\\n enum RelayCallStatus {\\n OK,\\n RelayedCallFailed,\\n RejectedByPreRelayed,\\n RejectedByForwarder,\\n RejectedByRecipientRevert,\\n PostRelayedFailed,\\n PaymasterBalanceChanged\\n }\\n\\n /**\\n * @notice Add new worker addresses controlled by the sender who must be a staked Relay Manager address.\\n * Emits a `RelayWorkersAdded` event.\\n * This function can be called multiple times, emitting new events.\\n */\\n function addRelayWorkers(address[] calldata newRelayWorkers) external;\\n\\n /**\\n * @notice The `RelayRegistrar` callback to notify the `RelayHub` that this `relayManager` has updated registration.\\n */\\n function onRelayServerRegistered(address relayManager) external;\\n\\n // Balance management\\n\\n /**\\n * @notice Deposits ether for a `Paymaster`, so that it can and pay for relayed transactions.\\n * :warning: **Warning** :warning: Unused balance can only be withdrawn by the holder itself, by calling `withdraw`.\\n * Emits a `Deposited` event.\\n */\\n function depositFor(address target) external payable;\\n\\n /**\\n * @notice Withdraws from an account's balance, sending it back to the caller.\\n * Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding.\\n * Emits a `Withdrawn` event.\\n */\\n function withdraw(address payable dest, uint256 amount) external;\\n\\n /**\\n * @notice Withdraws from an account's balance, sending funds to multiple provided addresses.\\n * Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding.\\n * Emits a `Withdrawn` event for each destination.\\n */\\n function withdrawMultiple(address payable[] memory dest, uint256[] memory amount) external;\\n\\n // Relaying\\n\\n\\n /**\\n * @notice Relays a transaction. For this to succeed, multiple conditions must be met:\\n * - `Paymaster`'s `preRelayCall` method must succeed and not revert.\\n * - the `msg.sender` must be a registered Relay Worker that the user signed to use.\\n * - the transaction's gas fees must be equal or larger than the ones that were signed by the sender.\\n * - the transaction must have enough gas to run all internal transactions if they use all gas available to them.\\n * - the `Paymaster` must have enough balance to pay the Relay Worker if all gas is spent.\\n *\\n * @notice If all conditions are met, the call will be relayed and the `Paymaster` charged.\\n *\\n * @param domainSeparatorName The name of the Domain Separator used to verify the EIP-712 signature\\n * @param maxAcceptanceBudget The maximum valid value for `paymaster.getGasLimits().acceptanceBudget` to return.\\n * @param relayRequest All details of the requested relayed call.\\n * @param signature The client's EIP-712 signature over the `relayRequest` struct.\\n * @param approvalData The dapp-specific data forwarded to the `Paymaster`'s `preRelayedCall` method.\\n * This value is **not** verified by the `RelayHub` in any way.\\n * As an example, it can be used to pass some kind of a third-party signature to the `Paymaster` for verification.\\n *\\n * Emits a `TransactionRelayed` event regardless of whether the transaction succeeded or failed.\\n */\\n function relayCall(\\n string calldata domainSeparatorName,\\n uint256 maxAcceptanceBudget,\\n GsnTypes.RelayRequest calldata relayRequest,\\n bytes calldata signature,\\n bytes calldata approvalData\\n )\\n external\\n returns (\\n bool paymasterAccepted,\\n uint256 charge,\\n IRelayHub.RelayCallStatus status,\\n bytes memory returnValue\\n );\\n\\n /**\\n * @notice In case the Relay Worker has been found to be in violation of some rules by the `Penalizer` contract,\\n * the `Penalizer` will call this method to execute a penalization.\\n * The `RelayHub` will look up the Relay Manager of the given Relay Worker and will forward the call to\\n * the `StakeManager` contract. The `RelayHub` does not perform the actual penalization either.\\n * @param relayWorker The address of the Relay Worker that committed a penalizable offense.\\n * @param beneficiary The address that called the `Penalizer` and will receive a reward for it.\\n */\\n function penalize(address relayWorker, address payable beneficiary) external;\\n\\n /**\\n * @notice Sets or changes the configuration of this `RelayHub`.\\n * @param _config The new configuration.\\n */\\n function setConfiguration(RelayHubConfig memory _config) external;\\n\\n /**\\n * @notice Sets or changes the minimum amount of a given `token` that needs to be staked so that the Relay Manager\\n * is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.\\n * @param token An array of addresses of ERC-20 compatible tokens.\\n * @param minimumStake An array of minimal amounts necessary for a corresponding token, in wei.\\n */\\n function setMinimumStakes(IERC20[] memory token, uint256[] memory minimumStake) external;\\n\\n /**\\n * @notice Deprecate hub by reverting all incoming `relayCall()` calls starting from a given timestamp\\n * @param _deprecationTime The timestamp in seconds after which the `RelayHub` stops serving transactions.\\n */\\n function deprecateHub(uint256 _deprecationTime) external;\\n\\n /**\\n * @notice\\n * @param relayManager\\n */\\n function escheatAbandonedRelayBalance(address relayManager) external;\\n\\n /**\\n * @notice The fee is expressed as a base fee in wei plus percentage of the actual charge.\\n * For example, a value '40' stands for a 40% fee, so the recipient will be charged for 1.4 times the spent amount.\\n * @param gasUsed An amount of gas used by the transaction.\\n * @param relayData The details of a transaction signed by the sender.\\n * @return The calculated charge, in wei.\\n */\\n function calculateCharge(uint256 gasUsed, GsnTypes.RelayData calldata relayData) external view returns (uint256);\\n\\n /**\\n * @notice The fee is expressed as a percentage of the actual charge.\\n * For example, a value '40' stands for a 40% fee, so the Relay Manager will only get 60% of the `charge`.\\n * @param charge The amount of Ether in wei the Paymaster will be charged for this transaction.\\n * @return The calculated devFee, in wei.\\n */\\n function calculateDevCharge(uint256 charge) external view returns (uint256);\\n /* getters */\\n\\n /// @return config The configuration of the `RelayHub`.\\n function getConfiguration() external view returns (RelayHubConfig memory config);\\n\\n /**\\n * @param token An address of an ERC-20 compatible tokens.\\n * @return The minimum amount of a given `token` that needs to be staked so that the Relay Manager\\n * is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.\\n */\\n function getMinimumStakePerToken(IERC20 token) external view returns (uint256);\\n\\n /**\\n * @param worker An address of the Relay Worker.\\n * @return The address of its Relay Manager.\\n */\\n function getWorkerManager(address worker) external view returns (address);\\n\\n /**\\n * @param manager An address of the Relay Manager.\\n * @return The count of Relay Workers associated with this Relay Manager.\\n */\\n function getWorkerCount(address manager) external view returns (uint256);\\n\\n /// @return An account's balance. It can be either a deposit of a `Paymaster`, or a revenue of a Relay Manager.\\n function balanceOf(address target) external view returns (uint256);\\n\\n /// @return The `StakeManager` address for this `RelayHub`.\\n function getStakeManager() external view returns (IStakeManager);\\n\\n /// @return The `Penalizer` address for this `RelayHub`.\\n function getPenalizer() external view returns (address);\\n\\n /// @return The `RelayRegistrar` address for this `RelayHub`.\\n function getRelayRegistrar() external view returns (address);\\n\\n /// @return The `BatchGateway` address for this `RelayHub`.\\n function getBatchGateway() external view returns (address);\\n\\n /**\\n * @notice Uses `StakeManager` to decide if the Relay Manager can be considered staked or not.\\n * Returns if the stake's token, amount and delay satisfy all requirements, reverts otherwise.\\n */\\n function verifyRelayManagerStaked(address relayManager) external view;\\n\\n /**\\n * @notice Uses `StakeManager` to check if the Relay Manager can be considered abandoned or not.\\n * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\\n */\\n function isRelayEscheatable(address relayManager) external view returns (bool);\\n\\n /// @return `true` if the `RelayHub` is deprecated, `false` it it is not deprecated and can serve transactions.\\n function isDeprecated() external view returns (bool);\\n\\n /// @return The timestamp from which the hub no longer allows relaying calls.\\n function getDeprecationTime() external view returns (uint256);\\n\\n /// @return The block number in which the contract has been deployed.\\n function getCreationBlock() external view returns (uint256);\\n\\n /// @return a SemVer-compliant version of the `RelayHub` contract.\\n function versionHub() external view returns (string memory);\\n\\n /// @return A total measurable amount of gas left to current execution. Same as 'gasleft()' for pure EVMs.\\n function aggregateGasleft() external view returns (uint256);\\n}\\n\\n\",\"keccak256\":\"0x0ab29ca5985c98f530e5985e3d9dd14f00d34527410ce980b51b26e57bb0121c\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/interfaces/IRelayRegistrar.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.6;\\n\\nimport \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\n\\n/**\\n * @title The RelayRegistrar Interface\\n * @notice The on-chain registrar for all registered Relay Managers.\\n *\\n * @notice The client can use an implementation of a `RelayRegistrar` to find relay registration info.\\n *\\n */\\ninterface IRelayRegistrar is IERC165 {\\n\\n /**\\n * @notice A struct containing all the information necessary to client to interact with the Relay Server.\\n */\\n struct RelayInfo {\\n //last registration block number\\n uint32 lastSeenBlockNumber;\\n //last registration block timestamp\\n uint40 lastSeenTimestamp;\\n //stake (first registration) block number\\n uint32 firstSeenBlockNumber;\\n //stake (first registration) block timestamp\\n uint40 firstSeenTimestamp;\\n bytes32[3] urlParts;\\n address relayManager;\\n }\\n\\n /**\\n * @notice Emitted when a relay server registers or updates its details.\\n * Looking up these events allows a client to discover registered Relay Servers.\\n */\\n event RelayServerRegistered(\\n address indexed relayManager,\\n address indexed relayHub,\\n bytes32[3] relayUrl\\n );\\n\\n /**\\n * @notice This function is called by Relay Servers in order to register or to update their registration.\\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\\n * @param url The URL of the Relay Server that is listening to the clients' requests.\\n */\\n function registerRelayServer(\\n address relayHub,\\n bytes32[3] calldata url\\n ) external;\\n\\n /**\\n * @return The block number in which the contract has been deployed.\\n */\\n function getCreationBlock() external view returns (uint256);\\n\\n /**\\n * @return The maximum age the relay is considered registered by default by this `RelayRegistrar`, in seconds.\\n */\\n function getRelayRegistrationMaxAge() external view returns (uint256);\\n\\n /**\\n * @notice Change the maximum relay registration age.\\n */\\n function setRelayRegistrationMaxAge(uint256) external;\\n\\n /**\\n * @param relayManager An address of a Relay Manager.\\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\\n * @return info All the details of the given Relay Manager's registration. Throws if relay not found for `RelayHub`.\\n */\\n function getRelayInfo(address relayHub, address relayManager) external view returns (RelayInfo memory info);\\n\\n /**\\n * @notice Read relay info of registered Relay Server from an on-chain storage.\\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\\n * @return info The list of `RelayInfo`s of registered Relay Servers\\n */\\n function readRelayInfos(\\n address relayHub\\n ) external view returns (\\n RelayInfo[] memory info\\n );\\n\\n /**\\n * @notice Read relay info of registered Relay Server from an on-chain storage.\\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\\n * @param maxCount The maximum amount of relays to be returned by this function.\\n * @param oldestBlockNumber The latest block number in which a Relay Server may be registered.\\n * @param oldestBlockTimestamp The latest block timestamp in which a Relay Server may be registered.\\n * @return info The list of `RelayInfo`s of registered Relay Servers\\n */\\n function readRelayInfosInRange(\\n address relayHub,\\n uint256 oldestBlockNumber,\\n uint256 oldestBlockTimestamp,\\n uint256 maxCount\\n ) external view returns (\\n RelayInfo[] memory info\\n );\\n}\\n\",\"keccak256\":\"0x9f4ac5bead0cc949f8e1b89f1666527286b282e86e57b59de533b3f650927cfd\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @title The StakeManager Interface\\n * @notice In order to prevent an attacker from registering a large number of unresponsive relays, the GSN requires\\n * the Relay Server to maintain a permanently locked stake in the system before being able to register.\\n *\\n * @notice Also, in some cases the behavior of a Relay Server may be found to be illegal by a `Penalizer` contract.\\n * In such case, the stake will never be returned to the Relay Server operator and will be slashed.\\n *\\n * @notice An implementation of this interface is tasked with keeping Relay Servers' stakes, made in any ERC-20 token.\\n * Note that the `RelayHub` chooses which ERC-20 tokens to support and how much stake is needed.\\n */\\ninterface IStakeManager is IERC165 {\\n\\n /// @notice Emitted when a `stake` or `unstakeDelay` are initialized or increased.\\n event StakeAdded(\\n address indexed relayManager,\\n address indexed owner,\\n IERC20 token,\\n uint256 stake,\\n uint256 unstakeDelay\\n );\\n\\n /// @notice Emitted once a stake is scheduled for withdrawal.\\n event StakeUnlocked(\\n address indexed relayManager,\\n address indexed owner,\\n uint256 withdrawTime\\n );\\n\\n /// @notice Emitted when owner withdraws `relayManager` funds.\\n event StakeWithdrawn(\\n address indexed relayManager,\\n address indexed owner,\\n IERC20 token,\\n uint256 amount\\n );\\n\\n /// @notice Emitted when an authorized `RelayHub` penalizes a `relayManager`.\\n event StakePenalized(\\n address indexed relayManager,\\n address indexed beneficiary,\\n IERC20 token,\\n uint256 reward\\n );\\n\\n /// @notice Emitted when a `relayManager` adds a new `RelayHub` to a list of authorized.\\n event HubAuthorized(\\n address indexed relayManager,\\n address indexed relayHub\\n );\\n\\n /// @notice Emitted when a `relayManager` removes a `RelayHub` from a list of authorized.\\n event HubUnauthorized(\\n address indexed relayManager,\\n address indexed relayHub,\\n uint256 removalTime\\n );\\n\\n /// @notice Emitted when a `relayManager` sets its `owner`. This is necessary to prevent stake hijacking.\\n event OwnerSet(\\n address indexed relayManager,\\n address indexed owner\\n );\\n\\n /// @notice Emitted when a `burnAddress` is changed.\\n event BurnAddressSet(\\n address indexed burnAddress\\n );\\n\\n /// @notice Emitted when a `devAddress` is changed.\\n event DevAddressSet(\\n address indexed devAddress\\n );\\n\\n /// @notice Emitted if Relay Server is inactive for an `abandonmentDelay` and contract owner initiates its removal.\\n event RelayServerAbandoned(\\n address indexed relayManager,\\n uint256 abandonedTime\\n );\\n\\n /// @notice Emitted to indicate an action performed by a relay server to prevent it from being marked as abandoned.\\n event RelayServerKeepalive(\\n address indexed relayManager,\\n uint256 keepaliveTime\\n );\\n\\n /// @notice Emitted when the stake of an abandoned relayer has been confiscated and transferred to the `devAddress`.\\n event AbandonedRelayManagerStakeEscheated(\\n address indexed relayManager,\\n address indexed owner,\\n IERC20 token,\\n uint256 amount\\n );\\n\\n /**\\n * @param stake - amount of ether staked for this relay\\n * @param unstakeDelay - number of seconds to elapse before the owner can retrieve the stake after calling 'unlock'\\n * @param withdrawTime - timestamp in seconds when 'withdraw' will be callable, or zero if the unlock has not been called\\n * @param owner - address that receives revenue and manages relayManager's stake\\n */\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelay;\\n uint256 withdrawTime;\\n uint256 abandonedTime;\\n uint256 keepaliveTime;\\n IERC20 token;\\n address owner;\\n }\\n\\n struct RelayHubInfo {\\n uint256 removalTime;\\n }\\n\\n /**\\n * @param devAddress - the address that will receive the 'abandoned' stake\\n * @param abandonmentDelay - the amount of time after which the relay can be marked as 'abandoned'\\n * @param escheatmentDelay - the amount of time after which the abandoned relay's stake and balance may be withdrawn to the `devAddress`\\n */\\n struct AbandonedRelayServerConfig {\\n address devAddress;\\n uint256 abandonmentDelay;\\n uint256 escheatmentDelay;\\n }\\n\\n /**\\n * @notice Set the owner of a Relay Manager. Called only by the RelayManager itself.\\n * Note that owners cannot transfer ownership - if the entry already exists, reverts.\\n * @param owner - owner of the relay (as configured off-chain)\\n */\\n function setRelayManagerOwner(address owner) external;\\n\\n /**\\n * @notice Put a stake for a relayManager and set its unstake delay.\\n * Only the owner can call this function. If the entry does not exist, reverts.\\n * The owner must give allowance of the ERC-20 token to the StakeManager before calling this method.\\n * It is the RelayHub who has a configurable list of minimum stakes per token. StakeManager accepts all tokens.\\n * @param token The address of an ERC-20 token that is used by the relayManager as a stake\\n * @param relayManager The address that represents a stake entry and controls relay registrations on relay hubs\\n * @param unstakeDelay The number of seconds to elapse before an owner can retrieve the stake after calling `unlock`\\n * @param amount The amount of tokens to be taken from the relayOwner and locked in the StakeManager as a stake\\n */\\n function stakeForRelayManager(IERC20 token, address relayManager, uint256 unstakeDelay, uint256 amount) external;\\n\\n /**\\n * @notice Schedule the unlocking of the stake. The `unstakeDelay` must pass before owner can call `withdrawStake`.\\n * @param relayManager The address of a Relay Manager whose stake is to be unlocked.\\n */\\n function unlockStake(address relayManager) external;\\n /**\\n * @notice Withdraw the unlocked stake.\\n * @param relayManager The address of a Relay Manager whose stake is to be withdrawn.\\n */\\n function withdrawStake(address relayManager) external;\\n\\n /**\\n * @notice Add the `RelayHub` to a list of authorized by this Relay Manager.\\n * This allows the RelayHub to penalize this Relay Manager. The `RelayHub` cannot trust a Relay it cannot penalize.\\n * @param relayManager The address of a Relay Manager whose stake is to be authorized for the new `RelayHub`.\\n * @param relayHub The address of a `RelayHub` to be authorized.\\n */\\n function authorizeHubByOwner(address relayManager, address relayHub) external;\\n\\n /**\\n * @notice Same as `authorizeHubByOwner` but can be called by the RelayManager itself.\\n */\\n function authorizeHubByManager(address relayHub) external;\\n\\n /**\\n * @notice Remove the `RelayHub` from a list of authorized by this Relay Manager.\\n * @param relayManager The address of a Relay Manager.\\n * @param relayHub The address of a `RelayHub` to be unauthorized.\\n */\\n function unauthorizeHubByOwner(address relayManager, address relayHub) external;\\n\\n /**\\n * @notice Same as `unauthorizeHubByOwner` but can be called by the RelayManager itself.\\n */\\n function unauthorizeHubByManager(address relayHub) external;\\n\\n /**\\n * Slash the stake of the relay relayManager. In order to prevent stake kidnapping, burns part of stake on the way.\\n * @param relayManager The address of a Relay Manager to be penalized.\\n * @param beneficiary The address that receives part of the penalty amount.\\n * @param amount A total amount of penalty to be withdrawn from stake.\\n */\\n function penalizeRelayManager(address relayManager, address beneficiary, uint256 amount) external;\\n\\n /**\\n * @notice Allows the contract owner to set the given `relayManager` as abandoned after a configurable delay.\\n * Its entire stake and balance will be taken from a relay if it does not respond to being marked as abandoned.\\n */\\n function markRelayAbandoned(address relayManager) external;\\n\\n /**\\n * @notice If more than `abandonmentDelay` has passed since the last Keepalive transaction, and relay manager\\n * has been marked as abandoned, and after that more that `escheatmentDelay` have passed, entire stake and\\n * balance will be taken from this relay.\\n */\\n function escheatAbandonedRelayStake(address relayManager) external;\\n\\n /**\\n * @notice Sets a new `keepaliveTime` for the given `relayManager`, preventing it from being marked as abandoned.\\n * Can be called by an authorized `RelayHub` or by the `relayOwner` address.\\n */\\n function updateRelayKeepaliveTime(address relayManager) external;\\n\\n /**\\n * @notice Check if the Relay Manager can be considered abandoned or not.\\n * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\\n */\\n function isRelayEscheatable(address relayManager) external view returns(bool);\\n\\n /**\\n * @notice Get the stake details information for the given Relay Manager.\\n * @param relayManager The address of a Relay Manager.\\n * @return stakeInfo The `StakeInfo` structure.\\n * @return isSenderAuthorizedHub `true` if the `msg.sender` for this call was a `RelayHub` that is authorized now.\\n * `false` if the `msg.sender` for this call is not authorized.\\n */\\n function getStakeInfo(address relayManager) external view returns (StakeInfo memory stakeInfo, bool isSenderAuthorizedHub);\\n\\n /**\\n * @return The maximum unstake delay this `StakeManger` allows. This is to prevent locking money forever by mistake.\\n */\\n function getMaxUnstakeDelay() external view returns (uint256);\\n\\n /**\\n * @notice Change the address that will receive the 'burned' part of the penalized stake.\\n * This is done to prevent malicious Relay Server from penalizing itself and breaking even.\\n */\\n function setBurnAddress(address _burnAddress) external;\\n\\n /**\\n * @return The address that will receive the 'burned' part of the penalized stake.\\n */\\n function getBurnAddress() external view returns (address);\\n\\n /**\\n * @notice Change the address that will receive the 'abandoned' stake.\\n * This is done to prevent Relay Servers that lost their keys from losing access to funds.\\n */\\n function setDevAddress(address _burnAddress) external;\\n\\n /**\\n * @return The structure that contains all configuration values for the 'abandoned' stake.\\n */\\n function getAbandonedRelayServerConfig() external view returns (AbandonedRelayServerConfig memory);\\n\\n /**\\n * @return the block number in which the contract has been deployed.\\n */\\n function getCreationBlock() external view returns (uint256);\\n\\n /**\\n * @return a SemVer-compliant version of the `StakeManager` contract.\\n */\\n function versionSM() external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x77035b55ca4c09cb499bc0cab3f9e791d77597b148dbfee8bf94ca6c0039c3e0\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/utils/GsnEip712Library.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../utils/GsnTypes.sol\\\";\\nimport \\\"../interfaces/IERC2771Recipient.sol\\\";\\nimport \\\"../forwarder/IForwarder.sol\\\";\\n\\nimport \\\"./GsnUtils.sol\\\";\\n\\n/**\\n * @title The ERC-712 Library for GSN\\n * @notice Bridge Library to convert a GSN RelayRequest into a valid `ForwardRequest` for a `Forwarder`.\\n */\\nlibrary GsnEip712Library {\\n // maximum length of return value/revert reason for 'execute' method. Will truncate result if exceeded.\\n uint256 private constant MAX_RETURN_SIZE = 1024;\\n\\n //copied from Forwarder (can't reference string constants even from another library)\\n string public constant GENERIC_PARAMS = \\\"address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data,uint256 validUntilTime\\\";\\n\\n bytes public constant RELAYDATA_TYPE = \\\"RelayData(uint256 maxFeePerGas,uint256 maxPriorityFeePerGas,uint256 transactionCalldataGasUsed,address relayWorker,address paymaster,address forwarder,bytes paymasterData,uint256 clientId)\\\";\\n\\n string public constant RELAY_REQUEST_NAME = \\\"RelayRequest\\\";\\n string public constant RELAY_REQUEST_SUFFIX = string(abi.encodePacked(\\\"RelayData relayData)\\\", RELAYDATA_TYPE));\\n\\n bytes public constant RELAY_REQUEST_TYPE = abi.encodePacked(\\n RELAY_REQUEST_NAME,\\\"(\\\",GENERIC_PARAMS,\\\",\\\", RELAY_REQUEST_SUFFIX);\\n\\n bytes32 public constant RELAYDATA_TYPEHASH = keccak256(RELAYDATA_TYPE);\\n bytes32 public constant RELAY_REQUEST_TYPEHASH = keccak256(RELAY_REQUEST_TYPE);\\n\\n\\n struct EIP712Domain {\\n string name;\\n string version;\\n uint256 chainId;\\n address verifyingContract;\\n }\\n\\n bytes32 public constant EIP712DOMAIN_TYPEHASH = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n\\n function splitRequest(\\n GsnTypes.RelayRequest calldata req\\n )\\n internal\\n pure\\n returns (\\n bytes memory suffixData\\n ) {\\n suffixData = abi.encode(\\n hashRelayData(req.relayData));\\n }\\n\\n //verify that the recipient trusts the given forwarder\\n // MUST be called by paymaster\\n function verifyForwarderTrusted(GsnTypes.RelayRequest calldata relayRequest) internal view {\\n (bool success, bytes memory ret) = relayRequest.request.to.staticcall(\\n abi.encodeWithSelector(\\n IERC2771Recipient.isTrustedForwarder.selector, relayRequest.relayData.forwarder\\n )\\n );\\n require(success, \\\"isTrustedForwarder: reverted\\\");\\n require(ret.length == 32, \\\"isTrustedForwarder: bad response\\\");\\n require(abi.decode(ret, (bool)), \\\"invalid forwarder for recipient\\\");\\n }\\n\\n function verifySignature(\\n string memory domainSeparatorName,\\n GsnTypes.RelayRequest calldata relayRequest,\\n bytes calldata signature\\n ) internal view {\\n (bytes memory suffixData) = splitRequest(relayRequest);\\n bytes32 _domainSeparator = domainSeparator(domainSeparatorName, relayRequest.relayData.forwarder);\\n IForwarder forwarder = IForwarder(payable(relayRequest.relayData.forwarder));\\n forwarder.verify(relayRequest.request, _domainSeparator, RELAY_REQUEST_TYPEHASH, suffixData, signature);\\n }\\n\\n function verify(\\n string memory domainSeparatorName,\\n GsnTypes.RelayRequest calldata relayRequest,\\n bytes calldata signature\\n ) internal view {\\n verifyForwarderTrusted(relayRequest);\\n verifySignature(domainSeparatorName, relayRequest, signature);\\n }\\n\\n function execute(\\n string memory domainSeparatorName,\\n GsnTypes.RelayRequest calldata relayRequest,\\n bytes calldata signature\\n ) internal returns (\\n bool forwarderSuccess,\\n bool callSuccess,\\n bytes memory ret\\n ) {\\n (bytes memory suffixData) = splitRequest(relayRequest);\\n bytes32 _domainSeparator = domainSeparator(domainSeparatorName, relayRequest.relayData.forwarder);\\n /* solhint-disable-next-line avoid-low-level-calls */\\n (forwarderSuccess, ret) = relayRequest.relayData.forwarder.call(\\n abi.encodeWithSelector(IForwarder.execute.selector,\\n relayRequest.request, _domainSeparator, RELAY_REQUEST_TYPEHASH, suffixData, signature\\n ));\\n if ( forwarderSuccess ) {\\n\\n //decode return value of execute:\\n (callSuccess, ret) = abi.decode(ret, (bool, bytes));\\n }\\n truncateInPlace(ret);\\n }\\n\\n //truncate the given parameter (in-place) if its length is above the given maximum length\\n // do nothing otherwise.\\n //NOTE: solidity warns unless the method is marked \\\"pure\\\", but it DOES modify its parameter.\\n function truncateInPlace(bytes memory data) internal pure {\\n MinLibBytes.truncateInPlace(data, MAX_RETURN_SIZE);\\n }\\n\\n function domainSeparator(string memory name, address forwarder) internal view returns (bytes32) {\\n return hashDomain(EIP712Domain({\\n name : name,\\n version : \\\"3\\\",\\n chainId : getChainID(),\\n verifyingContract : forwarder\\n }));\\n }\\n\\n function getChainID() internal view returns (uint256 id) {\\n /* solhint-disable no-inline-assembly */\\n assembly {\\n id := chainid()\\n }\\n }\\n\\n function hashDomain(EIP712Domain memory req) internal pure returns (bytes32) {\\n return keccak256(abi.encode(\\n EIP712DOMAIN_TYPEHASH,\\n keccak256(bytes(req.name)),\\n keccak256(bytes(req.version)),\\n req.chainId,\\n req.verifyingContract));\\n }\\n\\n function hashRelayData(GsnTypes.RelayData calldata req) internal pure returns (bytes32) {\\n return keccak256(abi.encode(\\n RELAYDATA_TYPEHASH,\\n req.maxFeePerGas,\\n req.maxPriorityFeePerGas,\\n req.transactionCalldataGasUsed,\\n req.relayWorker,\\n req.paymaster,\\n req.forwarder,\\n keccak256(req.paymasterData),\\n req.clientId\\n ));\\n }\\n}\\n\",\"keccak256\":\"0x73b5828c2578aea26dbd21cea00f1a245c94f9720ffd95932777ee6121e31972\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/utils/GsnTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.0;\\n\\nimport \\\"../forwarder/IForwarder.sol\\\";\\n\\ninterface GsnTypes {\\n /// @notice maxFeePerGas, maxPriorityFeePerGas, pctRelayFee and baseRelayFee must be validated inside of the paymaster's preRelayedCall in order not to overpay\\n struct RelayData {\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n uint256 transactionCalldataGasUsed;\\n address relayWorker;\\n address paymaster;\\n address forwarder;\\n bytes paymasterData;\\n uint256 clientId;\\n }\\n\\n //note: must start with the ForwardRequest to be an extension of the generic forwarder\\n struct RelayRequest {\\n IForwarder.ForwardRequest request;\\n RelayData relayData;\\n }\\n}\\n\",\"keccak256\":\"0x9fb51c540f32939f1ee291e3fa709be64f7c73485bd7b87c6624c3567dd42a1b\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/utils/GsnUtils.sol\":{\"content\":\"/* solhint-disable no-inline-assembly */\\n// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/MinLibBytes.sol\\\";\\nimport \\\"./GsnTypes.sol\\\";\\n\\n/**\\n * @title The GSN Solidity Utils Library\\n * @notice Some library functions used throughout the GSN Solidity codebase.\\n */\\nlibrary GsnUtils {\\n\\n bytes32 constant private RELAY_REQUEST_ID_MASK = 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\\n\\n /**\\n * @notice Calculate an identifier for the meta-transaction in a format similar to a transaction hash.\\n * Note that uniqueness relies on signature and may not be enforced if meta-transactions are verified\\n * with a different algorithm, e.g. when batching.\\n * @param relayRequest The `RelayRequest` for which an ID is being calculated.\\n * @param signature The signature for the `RelayRequest`. It is not validated here and may even remain empty.\\n */\\n function getRelayRequestID(GsnTypes.RelayRequest calldata relayRequest, bytes calldata signature)\\n internal\\n pure\\n returns (bytes32) {\\n return keccak256(abi.encode(relayRequest.request.from, relayRequest.request.nonce, signature)) & RELAY_REQUEST_ID_MASK;\\n }\\n\\n /**\\n * @notice Extract the method identifier signature from the encoded function call.\\n */\\n function getMethodSig(bytes memory msgData) internal pure returns (bytes4) {\\n return MinLibBytes.readBytes4(msgData, 0);\\n }\\n\\n /**\\n * @notice Extract a parameter from encoded-function block.\\n * see: https://solidity.readthedocs.io/en/develop/abi-spec.html#formal-specification-of-the-encoding\\n * The return value should be casted to the right type (`uintXXX`/`bytesXXX`/`address`/`bool`/`enum`).\\n * @param msgData Byte array containing a uint256 value.\\n * @param index Index in byte array of uint256 value.\\n * @return result uint256 value from byte array.\\n */\\n function getParam(bytes memory msgData, uint256 index) internal pure returns (uint256 result) {\\n return MinLibBytes.readUint256(msgData, 4 + index * 32);\\n }\\n\\n /// @notice Re-throw revert with the same revert data.\\n function revertWithData(bytes memory data) internal pure {\\n assembly {\\n revert(add(data,32), mload(data))\\n }\\n }\\n\\n}\\n\",\"keccak256\":\"0x7ea79bac2508612eba2c9372a7a4af953218b4ee2721e273f6d368e76b1ae7bb\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/utils/MinLibBytes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// minimal bytes manipulation required by GSN\\n// a minimal subset from 0x/LibBytes\\n/* solhint-disable no-inline-assembly */\\npragma solidity ^0.8.0;\\n\\nlibrary MinLibBytes {\\n\\n //truncate the given parameter (in-place) if its length is above the given maximum length\\n // do nothing otherwise.\\n //NOTE: solidity warns unless the method is marked \\\"pure\\\", but it DOES modify its parameter.\\n function truncateInPlace(bytes memory data, uint256 maxlen) internal pure {\\n if (data.length > maxlen) {\\n assembly { mstore(data, maxlen) }\\n }\\n }\\n\\n /// @dev Reads an address from a position in a byte array.\\n /// @param b Byte array containing an address.\\n /// @param index Index in byte array of address.\\n /// @return result address from byte array.\\n function readAddress(\\n bytes memory b,\\n uint256 index\\n )\\n internal\\n pure\\n returns (address result)\\n {\\n require (b.length >= index + 20, \\\"readAddress: data too short\\\");\\n\\n // Add offset to index:\\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\\n index += 20;\\n\\n // Read address from array memory\\n assembly {\\n // 1. Add index to address of bytes array\\n // 2. Load 32-byte word from memory\\n // 3. Apply 20-byte mask to obtain address\\n result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)\\n }\\n return result;\\n }\\n\\n function readBytes32(\\n bytes memory b,\\n uint256 index\\n )\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n require(b.length >= index + 32, \\\"readBytes32: data too short\\\" );\\n\\n // Read the bytes32 from array memory\\n assembly {\\n result := mload(add(b, add(index,32)))\\n }\\n return result;\\n }\\n\\n /// @dev Reads a uint256 value from a position in a byte array.\\n /// @param b Byte array containing a uint256 value.\\n /// @param index Index in byte array of uint256 value.\\n /// @return result uint256 value from byte array.\\n function readUint256(\\n bytes memory b,\\n uint256 index\\n )\\n internal\\n pure\\n returns (uint256 result)\\n {\\n result = uint256(readBytes32(b, index));\\n return result;\\n }\\n\\n function readBytes4(\\n bytes memory b,\\n uint256 index\\n )\\n internal\\n pure\\n returns (bytes4 result)\\n {\\n require(b.length >= index + 4, \\\"readBytes4: data too short\\\");\\n\\n // Read the bytes4 from array memory\\n assembly {\\n result := mload(add(b, add(index,32)))\\n // Solidity does not require us to clean the trailing bytes.\\n // We do it anyway\\n result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)\\n }\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x8063af8e0f134be3d794ad39bdc0041f33a16c91a4ee7abb968d4c15c8d10c54\",\"license\":\"MIT\"},\"@opengsn/contracts/src/utils/RelayHubValidator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"../utils/GsnTypes.sol\\\";\\n\\n/**\\n * @title The RelayHub Validator Library\\n * @notice Validates the `msg.data` received by the `RelayHub` does not contain unnecessary bytes.\\n * Including these extra bytes would allow the Relay Server to inflate transaction costs and overcharge the client.\\n */\\nlibrary RelayHubValidator {\\n\\n /// @notice Validate that encoded `relayCall` is properly packed without any extra bytes\\n function verifyTransactionPacking(\\n string calldata domainSeparatorName,\\n GsnTypes.RelayRequest calldata relayRequest,\\n bytes calldata signature,\\n bytes calldata approvalData\\n ) internal pure {\\n // abicoder v2: https://docs.soliditylang.org/en/latest/abi-spec.html\\n // each static param/member is 1 word\\n // struct (with dynamic members) has offset to struct which is 1 word\\n // dynamic member is 1 word offset to actual value, which is 1-word length and ceil(length/32) words for data\\n // relayCall has 5 method params,\\n // relayRequest: 2 members\\n // relayData 8 members\\n // ForwardRequest: 7 members\\n // total 21 32-byte words if all dynamic params are zero-length.\\n uint256 expectedMsgDataLen = 4 + 22 * 32 +\\n dynamicParamSize(bytes(domainSeparatorName)) +\\n dynamicParamSize(signature) +\\n dynamicParamSize(approvalData) +\\n dynamicParamSize(relayRequest.request.data) +\\n dynamicParamSize(relayRequest.relayData.paymasterData);\\n // zero-length signature is allowed in a batch relay transaction\\n require(expectedMsgDataLen == msg.data.length, \\\"extra msg.data bytes\\\" );\\n }\\n\\n // helper method for verifyTransactionPacking:\\n // size (in bytes) of the given \\\"bytes\\\" parameter. size include the length (32-byte word),\\n // and actual data size, rounded up to full 32-byte words\\n function dynamicParamSize(bytes calldata buf) internal pure returns (uint256) {\\n return 32 + ((buf.length + 31) & (type(uint256).max - 31));\\n }\\n}\\n\",\"keccak256\":\"0x9bfdfed6e057a234bef8158fc8336048784146e91cd59a2611cd748dbae310e6\",\"license\":\"GPL-3.0-only\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../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 * By default, the owner account will be the one that deploys the contract. This\\n * can 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 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\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 require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\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 require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\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\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/ERC165Checker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Library used to query support of an interface declared via {IERC165}.\\n *\\n * Note that these functions return the actual result of the query: they do not\\n * `revert` if an interface is not supported. It is up to the caller to decide\\n * what to do in these cases.\\n */\\nlibrary ERC165Checker {\\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\\n\\n /**\\n * @dev Returns true if `account` supports the {IERC165} interface.\\n */\\n function supportsERC165(address account) internal view returns (bool) {\\n // Any contract that implements ERC165 must explicitly indicate support of\\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\\n return\\n supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) &&\\n !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID);\\n }\\n\\n /**\\n * @dev Returns true if `account` supports the interface defined by\\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\\n *\\n * See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\\n // query support of both ERC165 as per the spec and support of _interfaceId\\n return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId);\\n }\\n\\n /**\\n * @dev Returns a boolean array where each value corresponds to the\\n * interfaces passed in and whether they're supported or not. This allows\\n * you to batch check interfaces for a contract where your expectation\\n * is that some interfaces may not be supported.\\n *\\n * See {IERC165-supportsInterface}.\\n *\\n * _Available since v3.4._\\n */\\n function getSupportedInterfaces(\\n address account,\\n bytes4[] memory interfaceIds\\n ) internal view returns (bool[] memory) {\\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\\n\\n // query support of ERC165 itself\\n if (supportsERC165(account)) {\\n // query support of each interface in interfaceIds\\n for (uint256 i = 0; i < interfaceIds.length; i++) {\\n interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]);\\n }\\n }\\n\\n return interfaceIdsSupported;\\n }\\n\\n /**\\n * @dev Returns true if `account` supports all the interfaces defined in\\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\\n *\\n * Batch-querying can lead to gas savings by skipping repeated checks for\\n * {IERC165} support.\\n *\\n * See {IERC165-supportsInterface}.\\n */\\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\\n // query support of ERC165 itself\\n if (!supportsERC165(account)) {\\n return false;\\n }\\n\\n // query support of each interface in interfaceIds\\n for (uint256 i = 0; i < interfaceIds.length; i++) {\\n if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) {\\n return false;\\n }\\n }\\n\\n // all interfaces supported\\n return true;\\n }\\n\\n /**\\n * @notice Query if a contract implements an interface, does not check ERC165 support\\n * @param account The address of the contract to query for support of an interface\\n * @param interfaceId The interface identifier, as specified in ERC-165\\n * @return true if the contract at account indicates support of the interface with\\n * identifier interfaceId, false otherwise\\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\\n * the behavior of this method is undefined. This precondition can be checked\\n * with {supportsERC165}.\\n *\\n * Some precompiled contracts will falsely indicate support for a given interface, so caution\\n * should be exercised when using this function.\\n *\\n * Interface identification is specified in ERC-165.\\n */\\n function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {\\n // prepare call\\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\\n\\n // perform static call\\n bool success;\\n uint256 returnSize;\\n uint256 returnValue;\\n assembly {\\n success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\\n returnSize := returndatasize()\\n returnValue := mload(0x00)\\n }\\n\\n return success && returnSize >= 0x20 && returnValue > 0;\\n }\\n}\\n\",\"keccak256\":\"0x5a08ad61f4e82b8a3323562661a86fb10b10190848073fdc13d4ac43710ffba5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(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; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // 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 require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\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 + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\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 + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.4.22 <0.9.0;\\n\\nlibrary console {\\n address constant CONSOLE_ADDRESS =\\n 0x000000000000000000636F6e736F6c652e6c6f67;\\n\\n function _sendLogPayloadImplementation(bytes memory payload) internal view {\\n address consoleAddress = CONSOLE_ADDRESS;\\n /// @solidity memory-safe-assembly\\n assembly {\\n pop(\\n staticcall(\\n gas(),\\n consoleAddress,\\n add(payload, 32),\\n mload(payload),\\n 0,\\n 0\\n )\\n )\\n }\\n }\\n\\n function _castToPure(\\n function(bytes memory) internal view fnIn\\n ) internal pure returns (function(bytes memory) pure fnOut) {\\n assembly {\\n fnOut := fnIn\\n }\\n }\\n\\n function _sendLogPayload(bytes memory payload) internal pure {\\n _castToPure(_sendLogPayloadImplementation)(payload);\\n }\\n\\n function log() internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n }\\n function logInt(int256 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n }\\n\\n function logUint(uint256 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n }\\n\\n function logString(string memory p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n }\\n\\n function logBool(bool p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n }\\n\\n function logAddress(address p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n }\\n\\n function logBytes(bytes memory p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n }\\n\\n function logBytes1(bytes1 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n }\\n\\n function logBytes2(bytes2 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n }\\n\\n function logBytes3(bytes3 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n }\\n\\n function logBytes4(bytes4 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n }\\n\\n function logBytes5(bytes5 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n }\\n\\n function logBytes6(bytes6 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n }\\n\\n function logBytes7(bytes7 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n }\\n\\n function logBytes8(bytes8 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n }\\n\\n function logBytes9(bytes9 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n }\\n\\n function logBytes10(bytes10 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n }\\n\\n function logBytes11(bytes11 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n }\\n\\n function logBytes12(bytes12 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n }\\n\\n function logBytes13(bytes13 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n }\\n\\n function logBytes14(bytes14 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n }\\n\\n function logBytes15(bytes15 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n }\\n\\n function logBytes16(bytes16 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n }\\n\\n function logBytes17(bytes17 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n }\\n\\n function logBytes18(bytes18 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n }\\n\\n function logBytes19(bytes19 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n }\\n\\n function logBytes20(bytes20 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n }\\n\\n function logBytes21(bytes21 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n }\\n\\n function logBytes22(bytes22 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n }\\n\\n function logBytes23(bytes23 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n }\\n\\n function logBytes24(bytes24 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n }\\n\\n function logBytes25(bytes25 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n }\\n\\n function logBytes26(bytes26 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n }\\n\\n function logBytes27(bytes27 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n }\\n\\n function logBytes28(bytes28 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n }\\n\\n function logBytes29(bytes29 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n }\\n\\n function logBytes30(bytes30 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n }\\n\\n function logBytes31(bytes31 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n }\\n\\n function logBytes32(bytes32 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n }\\n\\n function log(uint256 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n }\\n\\n function log(string memory p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n }\\n\\n function log(bool p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n }\\n\\n function log(address p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n }\\n\\n function log(uint256 p0, uint256 p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n }\\n\\n function log(uint256 p0, string memory p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n }\\n\\n function log(uint256 p0, bool p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n }\\n\\n function log(uint256 p0, address p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n }\\n\\n function log(string memory p0, uint256 p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n }\\n\\n function log(string memory p0, string memory p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n }\\n\\n function log(string memory p0, bool p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n }\\n\\n function log(string memory p0, address p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n }\\n\\n function log(bool p0, uint256 p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n }\\n\\n function log(bool p0, string memory p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n }\\n\\n function log(bool p0, bool p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n }\\n\\n function log(bool p0, address p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n }\\n\\n function log(address p0, uint256 p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n }\\n\\n function log(address p0, string memory p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n }\\n\\n function log(address p0, bool p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n }\\n\\n function log(address p0, address p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, bool p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, address p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, address p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, string memory p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, bool p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, bool p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, address p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, address p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, address p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, uint256 p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, string memory p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, string memory p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, bool p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, bool p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, bool p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, address p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, address p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, address p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, address p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, uint256 p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, uint256 p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, string memory p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, string memory p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, string memory p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, bool p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, bool p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, bool p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, bool p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, address p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, address p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, address p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, address p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n}\\n\",\"keccak256\":\"0x7434453e6d3b7d0e5d0eb7846ffdbc27f0ccf3b163591263739b628074dc103a\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x610120604052600019600c553480156200001857600080fd5b50604051620056c2380380620056c28339810160408190526200003b9162000331565b62000046336200008b565b43610100526001600160601b0319606086811b821660805285811b821660a05284811b821660c05283901b1660e0526200008081620000db565b505050505062000493565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620000e562000284565b60648160c0015160ff1610620001355760405162461bcd60e51b815260206004820152601060248201526f0c8caec40cccaca40e8dede40d0d2ced60831b60448201526064015b60405180910390fd5b8051600190815560208201516002556040808301516003556060830151600455608083015160055560a08301516006805460c086015160e08701516001600160501b0316600160a81b02600160a81b600160f81b031960ff909216600160a01b026001600160a81b03199093166001600160a01b039095169490941791909117169190911790556101008301516007805461ffff90921661ffff19909216919091179055517f4812ada68f7c2cdc9f4a4a09e157ea6b924e0ef40a4fa7aa074fa8f70b1e7247916200027991815481526001820154602082015260028201546040820152600382015460608201526004820154608082015260058201546001600160a01b03811660a08084019190915260ff9082901c1660c083015260a81c6001600160501b031660e082015260069091015461ffff166101008201526101200190565b60405180910390a150565b6000546001600160a01b03163314620002e05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200012c565b565b8051620002ef816200047a565b919050565b805161ffff81168114620002ef57600080fd5b80516001600160501b0381168114620002ef57600080fd5b805160ff81168114620002ef57600080fd5b60008060008060008587036101a08112156200034c57600080fd5b865162000359816200047a565b60208801519096506200036c816200047a565b60408801519095506200037f816200047a565b606088015190945062000392816200047a565b9250610120607f198201811315620003a957600080fd5b620003b362000442565b91506080880151825260a0880151602083015260c0880151604083015260e08801516060830152610100808901516080840152620003f3828a01620002e2565b60a0840152620004076101408a016200031f565b60c08401526200041b6101608a0162000307565b60e08401526200042f6101808a01620002f4565b9083015250949793965091945092919050565b60405161012081016001600160401b03811182821017156200047457634e487b7160e01b600052604160045260246000fd5b60405290565b6001600160a01b03811681146200049057600080fd5b50565b60805160601c60a05160601c60c05160601c60e05160601c6101005161519f6200052360003960006102420152600081816102eb015261081a0152600081816106f3015261108e0152600081816104250152612b8b0152600081816105c80152818161078b0152818161090c015281816127660152818161290101528181612c690152612d64015261519f6000f3fe6080604052600436106101f95760003560e01c80638e53548b1161010d578063ca64f9e7116100a0578063e6e22e121161006f578063e6e22e1214610664578063ebcd31ac14610684578063f2fde38b146106a4578063f3fef3a3146106c4578063f7908a74146106e457600080fd5b8063ca64f9e7146105b9578063d26152f9146105ec578063d904c7321461060c578063ddf737891461062e57600080fd5b8063af595dfc116100dc578063af595dfc14610528578063be7c76ad14610548578063c2da078614610581578063c7178230146105a157600080fd5b80638e53548b146104a75780639bcde3f3146104c7578063a6e61b60146104e7578063aa67c9191461051557600080fd5b80636bd50cef1161019057806372c1ab0c1161015f57806372c1ab0c146103f657806375dc7b4e146104165780638a09fb56146104495780638ac3b845146104695780638da5cb5b1461048957600080fd5b80636bd50cef146103595780636ca862e21461037b57806370a08231146103ab578063715018a6146103e157600080fd5b806345bdade7116101cc57806345bdade7146102a55780634f7de031146102ba57806351d85156146102dc57806359c4afc01461032357600080fd5b806301ffc9a7146101fe57806320ffd56d1461023357806339622167146102705780633c16e59a14610290575b600080fd5b34801561020a57600080fd5b5061021e61021936600461401c565b610717565b60405190151581526020015b60405180910390f35b34801561023f57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405190815260200161022a565b34801561027c57600080fd5b5061021e61028b366004613d66565b610769565b34801561029c57600080fd5b50600c54610262565b3480156102b157600080fd5b50610262610807565b3480156102c657600080fd5b506102da6102d5366004613d66565b61080f565b005b3480156102e857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b03909116815260200161022a565b34801561032f57600080fd5b5061026261033e366004613d66565b6001600160a01b03166000908152600a602052604090205490565b34801561036557600080fd5b5061036e61096b565b60405161022a9190614a48565b34801561038757600080fd5b5061039b6103963660046141b6565b610a4c565b60405161022a9493929190614847565b3480156103b757600080fd5b506102626103c6366004613d66565b6001600160a01b03166000908152600b602052604090205490565b3480156103ed57600080fd5b506102da6118cf565b34801561040257600080fd5b506102da610411366004613e5c565b6118e3565b34801561042257600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061030b565b34801561045557600080fd5b506102da610464366004613f24565b611ba4565b34801561047557600080fd5b50610262610484366004614401565b611cfb565b34801561049557600080fd5b506000546001600160a01b031661030b565b3480156104b357600080fd5b506102626104c236600461441a565b611d30565b3480156104d357600080fd5b506102da6104e23660046142e2565b611dc6565b3480156104f357600080fd5b506105076105023660046140d1565b611f6c565b60405161022a9291906148bb565b6102da610523366004613d66565b6123f8565b34801561053457600080fd5b506102da610543366004614401565b6124d9565b34801561055457600080fd5b5061030b610563366004613d66565b6001600160a01b039081166000908152600960205260409020541690565b34801561058d57600080fd5b506102da61059c366004613de8565b61255c565b3480156105ad57600080fd5b50600c5442101561021e565b3480156105c557600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061030b565b3480156105f857600080fd5b506102da610607366004613d66565b61273f565b34801561061857600080fd5b506106216128bd565b60405161022a9190614875565b34801561063a57600080fd5b50610262610649366004613d66565b6001600160a01b031660009081526008602052604090205490565b34801561067057600080fd5b506102da61067f366004613d66565b6128dd565b34801561069057600080fd5b506102da61069f366004613daf565b612b80565b3480156106b057600080fd5b506102da6106bf366004613d66565b612dc8565b3480156106d057600080fd5b506102da6106df366004613d83565b612e41565b3480156106f057600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061030b565b60006001600160e01b0319821663e9fb30f760e01b148061074857506001600160e01b03198216630704183b60e11b145b8061076357506301ffc9a760e01b6001600160e01b03198316145b92915050565b604051633962216760e01b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063396221679060240160206040518083038186803b1580156107cf57600080fd5b505afa1580156107e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107639190613fbe565b60005a905090565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461088c5760405162461bcd60e51b815260206004820152601d60248201527f63616c6c6572206973206e6f742072656c61792072656769737472617200000060448201526064015b60405180910390fd5b610895816128dd565b6001600160a01b0381166000908152600a60205260409020546108ed5760405162461bcd60e51b815260206004820152601060248201526f6e6f2072656c617920776f726b65727360801b6044820152606401610883565b6040516346dcbf0b60e01b81526001600160a01b0382811660048301527f000000000000000000000000000000000000000000000000000000000000000016906346dcbf0b90602401600060405180830381600087803b15801561095057600080fd5b505af1158015610964573d6000803e3d6000fd5b5050505050565b6109d3604051806101200160405280600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b03168152602001600060ff16815260200160006001600160501b03168152602001600061ffff1681525090565b5060408051610120810182526001548152600254602082015260035491810191909152600454606082015260055460808201526006546001600160a01b03811660a0830152600160a01b810460ff1660c0830152600160a81b90046001600160501b031660e082015260075461ffff1661010082015290565b60008060006060610a5b613af1565b610a63610807565b6040820152610a738a8a8a612ee4565b6101e082015260408051808201909152601881527f72656c617943616c6c2072656c617952657175657374496400000000000000006020820152610ab690612f49565b610ac4816101e00151612f8c565b610afd60405180606001604052806023815260200161514760239139610aea8c80614b5f565b610af8906020810190613d66565b612fd1565b610b34604051806060016040528060218152602001614eb960219139610b238c80614b5f565b610af8906040810190602001613d66565b610b63604051806060016040528060248152602001614fc260249139610b5a8c80614b5f565b6040013561301a565b610b92604051806060016040528060228152602001614eda60229139610b898c80614b5f565b6060013561301a565b610bc1604051806060016040528060248152602001614e9560249139610bb88c80614b5f565b6080013561301a565b610bf06040518060600160405280602d8152602001614de5602d9139610be78c80614b5f565b60c0013561301a565b610c1f6040518060600160405280602d8152602001614f37602d9139610c1960208d018d614b75565b3561301a565b610c51604051806060016040528060358152602001614f8d60359139610c4860208d018d614b75565b6020013561301a565b610c7a6040518060600160405280603b8152602001614efc603b9139610b5a60208d018d614b75565b610cb46040518060600160405280602c8152602001614db9602c9139610ca360208d018d614b75565b610af8906080810190606001613d66565b610cee6040518060600160405280602a815260200161511d602a9139610cdd60208d018d614b75565b610af89060a0810190608001613d66565b610d286040518060600160405280602a81526020016150f3602a9139610d1760208d018d614b75565b610af89060c081019060a001613d66565b610d5a604051806060016040528060298152602001614f6460299139610d5160208d018d614b75565b60e0013561301a565b610d986040518060400160405280601d81526020017f72656c617943616c6c20646f6d61696e536570617261746f724e616d65000000815250612f49565b610dd78d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f4992505050565b610e0b6040518060400160405280601381526020017272656c617943616c6c207369676e617475726560681b815250612f49565b610e4a89898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061305f92505050565b610e816040518060400160405280601681526020017572656c617943616c6c20617070726f76616c4461746160501b815250612f49565b610ec087878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061305f92505050565b610ee16040518060600160405280602381526020016150d060239139612f49565b610f36610eee8b80614b5f565b610efc9060a0810190614b19565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061305f92505050565b610f576040518060600160405280602e8152602001614fe6602e9139612f49565b610f75610f6760208c018c614b75565b610efc9060c0810190614b19565b610fb46040518060400160405280601d81526020017f72656c617943616c6c206d6178416363657074616e63654275646765740000008152508c61301a565b600c544210610ff65760405162461bcd60e51b815260206004820152600e60248201526d1a1d588819195c1c9958d85d195960921b6044820152606401610883565b60046110028b80614b5f565b6110109060a0810190614b19565b9050101561101f576000611074565b61107461102c8b80614b5f565b61103a9060a0810190614b19565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506130a2915050565b6001600160e01b0319166020820152336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148015906110bb57503215155b156111cf578761110d5760405162461bcd60e51b815260206004820181905260248201527f6d697373696e67207369676e6174757265206f722062616420676174657761796044820152606401610883565b33321461115c5760405162461bcd60e51b815260206004820152601860248201527f72656c617920776f726b6572206d75737420626520454f4100000000000000006044820152606401610883565b61116960208b018b614b75565b61117a906080810190606001613d66565b6001600160a01b0316336001600160a01b0316146111cf5760405162461bcd60e51b81526020600482015260126024820152712737ba1030903934b3b43a103bb7b935b2b960711b6044820152606401610883565b321561126d57600960006111e660208d018d614b75565b6111f7906080810190606001613d66565b6001600160a01b039081168252602082019290925260400160002054166101c0820181905261125f5760405162461bcd60e51b81526020600482015260146024820152732ab735b737bbb7103932b630bc903bb7b935b2b960611b6044820152606401610883565b61126d816101c001516128dd565b61127c8b8b8360400151613112565b61010083015260a08201526112968d8d8c8c8c8c8c61339c565b60025460405a6112a790603f614cce565b6112b19190614cac565b6112bb9190614ced565b6101208201526112c9610807565b61014082015260035460045461012083015160408401516112ed60208f018f614b75565b604001356112fb9190614c94565b6113059190614c94565b61130f9190614c94565b6113199190614c94565b81610200018181525050306001600160a01b031681610120015163a6e61b6060e01b8f8f8e8e8e8e8e8a60a0015161134f610807565b8c610200015161135f9190614ced565b8c610100015160405160240161137e9a999897969594939291906148db565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516113bc919061466d565b60006040518083038160008787f1925050503d80600081146113fa576040519150601f19603f3d011682016040523d82523d6000602084013e6113ff565b606091505b5061022083015215158152611412610807565b8161014001516114229190614ced565b60e0820152610220810151805161144191602091810182019101614093565b8260c0018360800182905282600681111561145e5761145e614d61565b600681111561146f5761146f614d61565b90525050608081015151156114c0577fa1478a4242848419db824250a0dddc645dca0d6a9b12ab1fd79b00145a0ba98e8160c0015182608001516040516114b79291906148bb565b60405180910390a15b80516116225760028160c0015160068111156114de576114de614d61565b148061154d57506114f260208b018b614b75565b60a082015151611506916040013590614c94565b8160e001511115801561154d575060038160c00151600681111561152c5761152c614d61565b148061154d575060048160c00151600681111561154b5761154b614d61565b145b15611622576101e081015161156560208c018c614b75565b6115769060a0810190608001613d66565b6101c08301516001600160a01b0391821691167f0c47510cb900901afca7c9e926892582a36fd3bb7f908142ccf0fb4382a2b6846115b48e80614b5f565b6115c2906020810190613d66565b6115cc8f80614b5f565b6115dd906040810190602001613d66565b3387602001518860e0015189608001516040516115ff96959493929190614772565b60405180910390a46000808260c0015183608001519450945094509450506118c0565b60045461162d610807565b826040015161163c9190614ced565b61164960208d018d614b75565b604001356116579190614c94565b6116619190614c94565b610160820181905261167a906104c260208d018d614b75565b935061168584611cfb565b61018082015283600b600061169d60208e018e614b75565b6116ae9060a0810190608001613d66565b6001600160a01b03166001600160a01b03168152602001908152602001600020546116d99190614ced565b600b60006116ea60208e018e614b75565b6116fb9060a0810190608001613d66565b6001600160a01b031681526020810191909152604001600020556101808101516117259085614ced565b6101c08201516001600160a01b03166000908152600b602052604090205461174d9190614c94565b6101c08201516001600160a01b03166000908152600b6020526040902055610180810151156117bd576101808101516006546001600160a01b03166000908152600b60205260409020546117a19190614c94565b6006546001600160a01b03166000908152600b60205260409020555b60006117c98b80614b5f565b6117d7906020810190613d66565b905060006117e58c80614b5f565b6117f6906040810190602001613d66565b9050600061180760208e018e614b75565b6118189060a0810190608001613d66565b9050836101e00151336001600160a01b0316856101c001516001600160a01b03167fd51ac07012398c2059ec53c6005fa8639657917bd2dbd72bc489a3c0eaaa7f168686868a602001518b60c001518f60405161187a96959493929190614724565b60405180910390a4505050326118a35760c08101516080909101516001955090925090506118c0565b60c001516040805160208101909152600081526001955090925090505b98509850985098945050505050565b6118d7613476565b6118e160006134d0565b565b3360005b8251811015611b9e576119886040518060400160405280601981526020017f77697468647261774d756c7469706c6520257320257320257300000000000000815250600b6000856001600160a01b03166001600160a01b031681526020019081526020016000205486848151811061196157611961614d77565b602002602001015186858151811061197b5761197b614d77565b6020026020010151613520565b6001600160a01b0382166000908152600b602052604090205483518490839081106119b5576119b5614d77565b6020026020010151811015611a015760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610883565b838281518110611a1357611a13614d77565b602002602001015181611a269190614ced565b6001600160a01b0384166000908152600b60205260408120919091558551869084908110611a5657611a56614d77565b60200260200101516001600160a01b0316858481518110611a7957611a79614d77565b602002602001015160405160006040518083038185875af1925050503d8060008114611ac1576040519150601f19603f3d011682016040523d82523d6000602084013e611ac6565b606091505b5050905080611b0a5760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610883565b858381518110611b1c57611b1c614d77565b60200260200101516001600160a01b0316846001600160a01b03167fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb878681518110611b6a57611b6a614d77565b6020026020010151604051611b8191815260200190565b60405180910390a350508080611b9690614d30565b9150506118e7565b50505050565b611bac613476565b8051825114611bfd5760405162461bcd60e51b815260206004820152601e60248201527f7365744d696e696d756d5374616b65733a2077726f6e67206c656e67746800006044820152606401610883565b60005b8251811015611cf657818181518110611c1b57611c1b614d77565b602002602001015160086000858481518110611c3957611c39614d77565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055507ffb7510fe755f485459ee8ed619d4a0addc092c230ff47e760a62aeba78ebb9e3838281518110611c9857611c98614d77565b6020026020010151838381518110611cb257611cb2614d77565b6020026020010151604051611cdc9291906001600160a01b03929092168252602082015260400190565b60405180910390a180611cee81614d30565b915050611c00565b505050565b600654600090600160a01b900460ff16611d1757506000919050565b600654606490600160a01b900460ff1683020492915050565b600080823560208401351415611d4857506000611d4b565b50485b6000611d678435611d623a81602089013587614c94565b613569565b600754909150606490611d7e9061ffff1682614c6e565b61ffff16611d8c8388614cce565b611d969190614cce565b611da09190614cac565b600654611dbd9190600160a81b90046001600160501b0316614c94565b95945050505050565b611dce613476565b60648160c0015160ff1610611e185760405162461bcd60e51b815260206004820152601060248201526f0c8caec40cccaca40e8dede40d0d2ced60831b6044820152606401610883565b8051600190815560208201516002556040808301516003556060830151600455608083015160055560a08301516006805460c086015160e08701516001600160501b0316600160a81b0269ffffffffffffffffffff60a81b1960ff909216600160a01b026001600160a81b03199093166001600160a01b039095169490941791909117169190911790556101008301516007805461ffff90921661ffff19909216919091179055517f4812ada68f7c2cdc9f4a4a09e157ea6b924e0ef40a4fa7aa074fa8f70b1e724791611f6191815481526001820154602082015260028201546040820152600382015460608201526004820154608082015260058201546001600160a01b03811660a08084019190915260ff9082901c1660c08301526001600160501b0360a89190911c1660e082015260069091015461ffff166101008201526101200190565b60405180910390a150565b60006060611fc6604051806101200160405280600081526020016000815260200160008152602001600080191681526020016000151581526020016060815260200160608152602001606081526020016000151581525090565b611fce610807565b81525a611fdb9086614ced565b602082015233301461202f5760405162461bcd60e51b815260206004820152601a60248201527f4d7573742062652063616c6c65642062792052656c61794875620000000000006044820152606401610883565b600b600061204060208e018e614b75565b6120519060a0810190608001613d66565b6001600160a01b0316815260208101919091526040908101600020548282015251622f977560e21b90612092908d908d908d908d908d908b90602401614aca565b60408051601f19818403018152919052602080820180516001600160e01b03166001600160e01b03199094169390931790925260e08301526000906060906120dc908e018e614b75565b6120ed9060a0810190608001613d66565b6001600160a01b031688602001358460e0015160405161210d919061466d565b60006040518083038160008787f1925050503d806000811461214b576040519150601f19603f3d011682016040523d82523d6000602084013e612150565b606091505b5090925090508161216f5761216481613581565b61216f60028261358d565b808060200190518101906121839190614046565b8460c001856101000182151515158152508290525050505060006121ed8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8d6135c6565b60a08501521515608084015290508061220f5761220f60038360a0015161358d565b816101000151801561222357508160800151155b156122375761223760048360a0015161358d565b506376fa01c360e01b8160c001518260800151612252610807565b845161225e9190614ced565b846020015161226d9190614c94565b8e806020019061227d9190614b75565b6040516024016122909493929190614888565b60408051601f19818403018152919052602080820180516001600160e01b03166001600160e01b03199094169390931790925260e083015260009081906122d9908e018e614b75565b6122ea9060a0810190608001613d66565b6001600160a01b031688604001358460e0015160405161230a919061466d565b60006040518083038160008787f1925050503d8060008114612348576040519150601f19603f3d011682016040523d82523d6000602084013e61234d565b606091505b5091509150816123625761236260058261358d565b50506040810151600b600061237a60208f018f614b75565b61238b9060a0810190608001613d66565b6001600160a01b03166001600160a01b031681526020019081526020016000205410156123cc576123cc60066040518060200160405280600081525061358d565b80608001516123dc5760016123df565b60005b8160a0015192509250509a509a98505050505050505050565b6124126001600160a01b0382166370d596f560e11b6137ac565b61245e5760405162461bcd60e51b815260206004820181905260248201527f746172676574206973206e6f7420612076616c696420495061796d61737465726044820152606401610883565b6001600160a01b0381166000908152600b60205260409020543490612484908290614c94565b6001600160a01b0383166000818152600b6020908152604091829020939093555183815233927f8752a472e571a816aea92eec8dae9baf628e840f4929fbcc2d155e6233ff68a7910160405180910390a35050565b6124e1613476565b600c5442106125275760405162461bcd60e51b8152602060048201526012602482015271105b1c9958591e4819195c1c9958d85d195960721b6044820152606401610883565b600c8190556040518181527f1c0aa0c666483fbf0cf795d9d646ea3552d1e3008162ba9ab1d6d6dfd8c6ec6b90602001611f61565b336000818152600a6020526040812054612577908490614c94565b6001600160a01b0383166000908152600a602052604090208190556001549091508111156125da5760405162461bcd60e51b815260206004820152601060248201526f746f6f206d616e7920776f726b65727360801b6044820152606401610883565b6125e3826128dd565b60005b838110156126f357600060098187878581811061260557612605614d77565b905060200201602081019061261a9190613d66565b6001600160a01b03908116825260208201929092526040016000205416146126845760405162461bcd60e51b815260206004820152601960248201527f7468697320776f726b6572206861732061206d616e61676572000000000000006044820152606401610883565b826009600087878581811061269b5761269b614d77565b90506020020160208101906126b09190613d66565b6001600160a01b039081168252602082019290925260400160002080546001600160a01b03191692909116919091179055806126eb81614d30565b9150506125e6565b50816001600160a01b03167febf4a9bffb39f7c5dbf3f65540183b9381ae226ac3d0a45b4cad484713bd4a28858584604051612731939291906147f1565b60405180910390a250505050565b612747613476565b604051633962216760e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063396221679060240160206040518083038186803b1580156127a857600080fd5b505afa1580156127bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e09190613fbe565b61282c5760405162461bcd60e51b815260206004820181905260248201527f72656c617920736572766572206e6f74206573636865617461626c65207965746044820152606401610883565b6001600160a01b038082166000908152600b60205260408082208054908390556006549093168252902054612862908290614c94565b6006546001600160a01b039081166000908152600b60209081526040918290209390935551838152908416917f3fb672a061b9c3ab083062a9a8ff532d341e5fa42145b91f3922a711ae135659910160405180910390a25050565b6060604051806060016040528060228152602001614e1260229139905090565b60405163c345315360e01b81526001600160a01b03828116600483015260009182917f0000000000000000000000000000000000000000000000000000000000000000169063c3453153906024016101006040518083038186803b15801561294457600080fd5b505afa158015612958573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061297c9190614375565b60a0820180516001600160a01b03908116600090815260086020526040902054915193955091935091166129ed5760405162461bcd60e51b81526020600482015260186024820152771c995b185e481b585b9859d95c881b9bdd081cdd185ad95960421b6044820152606401610883565b8251811115612a3e5760405162461bcd60e51b815260206004820152601960248201527f7374616b6520616d6f756e7420697320746f6f20736d616c6c000000000000006044820152606401610883565b80612a8b5760405162461bcd60e51b815260206004820152601f60248201527f7374616b696e67207468697320746f6b656e20697320666f7262696464656e006044820152606401610883565b60055460208401511015612ae15760405162461bcd60e51b815260206004820152601a60248201527f756e7374616b652064656c617920697320746f6f20736d616c6c0000000000006044820152606401610883565b604083015115612b335760405162461bcd60e51b815260206004820152601860248201527f7374616b6520686173206265656e2077697468647261776e00000000000000006044820152606401610883565b81611b9e5760405162461bcd60e51b815260206004820181905260248201527f7468697320687562206973206e6f7420617574686f72697a656420627920534d6044820152606401610883565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614612be85760405162461bcd60e51b815260206004820152600d60248201526c2737ba103832b730b634bd32b960991b6044820152606401610883565b6001600160a01b038083166000908152600960205260409020541680612c475760405162461bcd60e51b81526020600482015260146024820152732ab735b737bbb7103932b630bc903bb7b935b2b960611b6044820152606401610883565b60405163c345315360e01b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063c3453153906024016101006040518083038186803b158015612cae57600080fd5b505afa158015612cc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce69190614375565b508051909150612d335760405162461bcd60e51b81526020600482015260186024820152771c995b185e481b585b9859d95c881b9bdd081cdd185ad95960421b6044820152606401610883565b805160405163026822bd60e21b81526001600160a01b038481166004830152858116602483015260448201929092527f0000000000000000000000000000000000000000000000000000000000000000909116906309a08af490606401600060405180830381600087803b158015612daa57600080fd5b505af1158015612dbe573d6000803e3d6000fd5b5050505050505050565b612dd0613476565b6001600160a01b038116612e355760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610883565b612e3e816134d0565b50565b6040805160018082528183019092526000916020808301908036833750506040805160018082528183019092529293506000929150602080830190803683370190505090508282600081518110612e9a57612e9a614d77565b6020026020010181815250508381600081518110612eba57612eba614d77565b60200260200101906001600160a01b031690816001600160a01b031681525050611b9e81836118e3565b60006001600160e01b03612ef88580614b5f565b612f06906020810190613d66565b612f108680614b5f565b608001358585604051602001612f2994939291906147c9565b604051602081830303815290604052805190602001201690509392505050565b612e3e81604051602401612f5d9190614875565b60408051601f198184030181529190526020810180516001600160e01b031663104c13eb60e21b1790526137c8565b612e3e81604051602401612fa291815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166327b7cf8560e01b1790526137c8565b6130168282604051602401612fe7929190614971565b60408051601f198184030181529190526020810180516001600160e01b031663319af33360e01b1790526137c8565b5050565b613016828260405160240161303092919061499b565b60408051601f198184030181529190526020810180516001600160e01b0316632d839cb360e21b1790526137c8565b612e3e816040516024016130739190614875565b60408051601f198184030181529190526020810180516001600160e01b03166305f3bfab60e11b1790526137c8565b60006130af826004614c94565b835110156130ff5760405162461bcd60e51b815260206004820152601a60248201527f726561644279746573343a206461746120746f6f2073686f72740000000000006044820152606401610883565b5001602001516001600160e01b03191690565b61313d6040518060800160405280600081526020016000815260200160008152602001600081525090565b600061314c6020850185614b75565b61315d9060a0810190608001613d66565b6001600160a01b031663b039a88f61c3506040518263ffffffff1660e01b815260040160806040518083038187803b15801561319857600080fd5b5086fa1580156131ac573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906131d1919061427d565b60608101519092503611156132285760405162461bcd60e51b815260206004820152601760248201527f6d73672e64617461206578636565646564206c696d69740000000000000000006044820152606401610883565b81518510156132795760405162461bcd60e51b815260206004820152601a60248201527f616363657074616e63652062756467657420746f6f20686967680000000000006044820152606401610883565b6020820151825110156132ce5760405162461bcd60e51b815260206004820152601960248201527f616363657074616e63652062756467657420746f6f206c6f77000000000000006044820152606401610883565b826132dc6020860186614b75565b604001356132ea9190614c94565b905060006132ff826104c26020880188614b75565b9050600b60006133126020880188614b75565b6133239060a0810190608001613d66565b6001600160a01b03166001600160a01b03168152602001908152602001600020548111156133935760405162461bcd60e51b815260206004820152601960248201527f5061796d61737465722062616c616e636520746f6f206c6f77000000000000006044820152606401610883565b50935093915050565b60006133c16133ae6020880188614b75565b6133bc9060c0810190614b19565b6137d1565b6133dc6133ce8880614b5f565b6133bc9060a0810190614b19565b6133e685856137d1565b6133f088886137d1565b6133fa8c8c6137d1565b613406906102c4614c94565b6134109190614c94565b61341a9190614c94565b6134249190614c94565b61342e9190614c94565b9050368114612dbe5760405162461bcd60e51b81526020600482015260146024820152736578747261206d73672e6461746120627974657360601b6044820152606401610883565b6000546001600160a01b031633146118e15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610883565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611b9e8484848460405160240161353a94939291906149bd565b60408051601f198184030181529190526020810180516001600160e01b03166327827ee360e11b1790526137c8565b6000818310613578578161357a565b825b9392505050565b612e3e816104006137f7565b600082826040516020016135a29291906148bb565b60405160208183030381529060405290506135bc81613581565b8051602082018181fd5b600080606060006135d687613804565b90506000613601896135eb60208b018b614b75565b6135fc9060c081019060a001613d66565b613843565b90506136106020890189614b75565b6136219060c081019060a001613d66565b6001600160a01b031663e024dc7f60e01b61363c8a80614b5f565b836040518060400160405280600c81526020016b14995b185e54995c5d595cdd60a21b8152506040518060a0016040528060618152602001614e34606191396040518060e0016040528060bc815260200161501460bc91396040516020016136a491906146e8565b60408051601f19818403018152908290526136c3939291602001614689565b60405160208183030381529060405280519060200120868c8c6040516024016136f1969594939291906149f5565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161372f919061466d565b6000604051808303816000865af19150503d806000811461376c576040519150601f19603f3d011682016040523d82523d6000602084013e613771565b606091505b509095509250841561379757828060200190518101906137919190613fd9565b90945092505b6137a083613581565b50509450945094915050565b60006137b783613896565b801561357a575061357a83836138c9565b612e3e81613952565b60006137e0601f600019614ced565b6137eb83601f614c94565b61357a91166020614c94565b8082511115613016579052565b606061381b6138166020840184614b75565b613973565b60405160200161382d91815260200190565b6040516020818303038152906040529050919050565b600061357a6040518060800160405280858152602001604051806040016040528060018152602001603360f81b815250815260200161387f4690565b8152602001846001600160a01b0316815250613a71565b60006138a9826301ffc9a760e01b6138c9565b801561076357506138c2826001600160e01b03196138c9565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d9150600051905082801561393b575060208210155b80156139475750600081115b979650505050505050565b60006a636f6e736f6c652e6c6f679050600080835160208501845afa505050565b60006040518060e0016040528060bc815260200161501460bc913980516020918201209083359084013560408501356139b26080870160608801613d66565b6139c260a0880160808901613d66565b6139d260c0890160a08a01613d66565b6139df60c08a018a614b19565b6040516139ed92919061465d565b604051908190038120613a54989796959493929160e08c0135906020019889526020890197909752604088019590955260608701939093526001600160a01b039182166080870152811660a08601521660c084015260e08301526101008201526101200190565b604051602081830303815290604052805190602001209050919050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82600001518051906020012083602001518051906020012084604001518560600151604051602001613a549594939291909485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b60405180610240016040528060001515815260200160006001600160e01b0319168152602001600081526020016060815260200160608152602001613b576040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016060815260200160006001600160a01b031681526020016000801916815260200160008152602001606081525090565b8035613bc881614da3565b919050565b600082601f830112613bde57600080fd5b81356020613bf3613bee83614c06565b614bd6565b80838252828201915082860187848660051b8901011115613c1357600080fd5b60005b85811015613c3257813584529284019290840190600101613c16565b5090979650505050505050565b80518015158114613bc857600080fd5b60008083601f840112613c6157600080fd5b5081356001600160401b03811115613c7857600080fd5b602083019150836020828501011115613c9057600080fd5b9250929050565b600082601f830112613ca857600080fd5b81516001600160401b03811115613cc157613cc1614d8d565b613cd4601f8201601f1916602001614bd6565b818152846020838601011115613ce957600080fd5b613cfa826020830160208701614d04565b949350505050565b600060808284031215613d1457600080fd5b50919050565b600060408284031215613d1457600080fd5b803561ffff81168114613bc857600080fd5b803560ff81168114613bc857600080fd5b80356001600160501b0381168114613bc857600080fd5b600060208284031215613d7857600080fd5b813561357a81614da3565b60008060408385031215613d9657600080fd5b8235613da181614da3565b946020939093013593505050565b60008060408385031215613dc257600080fd5b8235613dcd81614da3565b91506020830135613ddd81614da3565b809150509250929050565b60008060208385031215613dfb57600080fd5b82356001600160401b0380821115613e1257600080fd5b818501915085601f830112613e2657600080fd5b813581811115613e3557600080fd5b8660208260051b8501011115613e4a57600080fd5b60209290920196919550909350505050565b60008060408385031215613e6f57600080fd5b82356001600160401b0380821115613e8657600080fd5b818501915085601f830112613e9a57600080fd5b81356020613eaa613bee83614c06565b8083825282820191508286018a848660051b8901011115613eca57600080fd5b600096505b84871015613ef6578035613ee281614da3565b835260019690960195918301918301613ecf565b5096505086013592505080821115613f0d57600080fd5b50613f1a85828601613bcd565b9150509250929050565b60008060408385031215613f3757600080fd5b82356001600160401b0380821115613f4e57600080fd5b818501915085601f830112613f6257600080fd5b81356020613f72613bee83614c06565b8083825282820191508286018a848660051b8901011115613f9257600080fd5b600096505b84871015613ef6578035613faa81614da3565b835260019690960195918301918301613f97565b600060208284031215613fd057600080fd5b61357a82613c3f565b60008060408385031215613fec57600080fd5b613ff583613c3f565b915060208301516001600160401b0381111561401057600080fd5b613f1a85828601613c97565b60006020828403121561402e57600080fd5b81356001600160e01b03198116811461357a57600080fd5b6000806040838503121561405957600080fd5b82516001600160401b0381111561406f57600080fd5b61407b85828601613c97565b92505061408a60208401613c3f565b90509250929050565b600080604083850312156140a657600080fd5b8251600781106140b557600080fd5b60208401519092506001600160401b0381111561401057600080fd5b6000806000806000806000806000806101408b8d0312156140f157600080fd5b8a356001600160401b038082111561410857600080fd5b6141148e838f01613c4f565b909c509a5060208d013591508082111561412d57600080fd5b6141398e838f01613d1a565b995060408d013591508082111561414f57600080fd5b61415b8e838f01613c4f565b909950975060608d013591508082111561417457600080fd5b506141818d828e01613c4f565b909650945061419590508c60808d01613d02565b92506101008b013591506101208b013590509295989b9194979a5092959850565b60008060008060008060008060a0898b0312156141d257600080fd5b88356001600160401b03808211156141e957600080fd5b6141f58c838d01613c4f565b909a50985060208b0135975060408b013591508082111561421557600080fd5b6142218c838d01613d1a565b965060608b013591508082111561423757600080fd5b6142438c838d01613c4f565b909650945060808b013591508082111561425c57600080fd5b506142698b828c01613c4f565b999c989b5096995094979396929594505050565b60006080828403121561428f57600080fd5b604051608081018181106001600160401b03821117156142b1576142b1614d8d565b8060405250825181526020830151602082015260408301516040820152606083015160608201528091505092915050565b600061012082840312156142f557600080fd5b6142fd614b8b565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261433560a08401613bbd565b60a082015261434660c08401613d3e565b60c082015261435760e08401613d4f565b60e082015261010061436a818501613d2c565b908201529392505050565b60008082840361010081121561438a57600080fd5b60e081121561439857600080fd5b506143a1614bb4565b835181526020840151602082015260408401516040820152606084015160608201526080840151608082015260a08401516143db81614da3565b60a082015260c08401516143ee81614da3565b60c0820152915061408a60e08401613c3f565b60006020828403121561441357600080fd5b5035919050565b6000806040838503121561442d57600080fd5b8235915060208301356001600160401b0381111561444a57600080fd5b83016101008186031215613ddd57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000815180845261449e816020860160208601614d04565b601f01601f19169290920160200192915050565b600781106144d057634e487b7160e01b600052602160045260246000fd5b9052565b600081356144e181614da3565b6001600160a01b0390811684526020830135906144fd82614da3565b16602084015260408281013590840152606080830135908401526080808301359084015261452e60a0830183614c29565b60e060a086015261454360e08601828461445d565b91505060c083013560c08501528091505092915050565b6000610100823584526020830135602085015260408301356040850152606083013561458581614da3565b6001600160a01b0390811660608601526080840135906145a482614da3565b16608085015260a08301356145b881614da3565b6001600160a01b031660a08501526145d360c0840184614c29565b8260c08701526145e6838701828461445d565b9250505060e083013560e08501528091505092915050565b6000813582360360de198101821261461557600080fd5b60408552614628604086018584016144d4565b9150602084013560fe198201811261463f57600080fd5b85830360208701526146538386830161455a565b9695505050505050565b8183823760009101908152919050565b6000825161467f818460208701614d04565b9190910192915050565b6000845161469b818460208901614d04565b600560fb1b90830190815284516146b9816001840160208901614d04565b600b60fa1b6001929091019182015283516146db816002840160208801614d04565b0160020195945050505050565b7352656c6179446174612072656c6179446174612960601b815260008251614717816014850160208701614d04565b9190910160140192915050565b6001600160a01b0387811682528681166020830152851660408201526001600160e01b03198416606082015260c0810161476160808301856144b2565b8260a0830152979650505050505050565b6001600160a01b0387811682528681166020830152851660408201526001600160e01b0319841660608201526080810183905260c060a082018190526000906147bd90830184614486565b98975050505050505050565b60018060a01b038516815283602082015260606040820152600061465360608301848661445d565b6040808252810183905260008460608301825b8681101561483457823561481781614da3565b6001600160a01b0316825260209283019290910190600101614804565b5060209390930193909352509392505050565b841515815283602082015261485f60408201846144b2565b6080606082015260006146536080830184614486565b60208152600061357a6020830184614486565b60808152600061489b6080830187614486565b85151560208401528460408401528281036060840152613947818561455a565b6148c581846144b2565b604060208201526000613cfa6040830184614486565b60006101408083526148f08184018d8f61445d565b90508281036020840152614904818c6145fe565b90508281036040840152614919818a8c61445d565b9050828103606084015261492e81888a61445d565b86516080850152602087015160a0850152604087015160c085015260609096015160e0840152505061010081019290925261012090910152979650505050505050565b6040815260006149846040830185614486565b905060018060a01b03831660208301529392505050565b6040815260006149ae6040830185614486565b90508260208301529392505050565b6080815260006149d06080830187614486565b6020830195909552506001600160a01b03929092166040830152606090910152919050565b60a081526000614a0860a08301896144d4565b8760208401528660408401528281036060840152614a268187614486565b90508281036080840152614a3b81858761445d565b9998505050505050505050565b600061012082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260018060a01b0360a08401511660a083015260ff60c08401511660c083015260e0830151614ab660e08401826001600160501b03169052565b506101009283015161ffff16919092015290565b608081526000614add60808301896145fe565b8281036020840152614af081888a61445d565b90508281036040840152614b0581868861445d565b915050826060830152979650505050505050565b6000808335601e19843603018112614b3057600080fd5b8301803591506001600160401b03821115614b4a57600080fd5b602001915036819003821315613c9057600080fd5b6000823560de1983360301811261467f57600080fd5b6000823560fe1983360301811261467f57600080fd5b60405161012081016001600160401b0381118282101715614bae57614bae614d8d565b60405290565b60405160e081016001600160401b0381118282101715614bae57614bae614d8d565b604051601f8201601f191681016001600160401b0381118282101715614bfe57614bfe614d8d565b604052919050565b60006001600160401b03821115614c1f57614c1f614d8d565b5060051b60200190565b6000808335601e19843603018112614c4057600080fd5b83016020810192503590506001600160401b03811115614c5f57600080fd5b803603831315613c9057600080fd5b600061ffff808316818516808303821115614c8b57614c8b614d4b565b01949350505050565b60008219821115614ca757614ca7614d4b565b500190565b600082614cc957634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615614ce857614ce8614d4b565b500290565b600082821015614cff57614cff614d4b565b500390565b60005b83811015614d1f578181015183820152602001614d07565b83811115611b9e5750506000910152565b6000600019821415614d4457614d44614d4b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114612e3e57600080fdfe72656c617943616c6c2072656c6179526571756573742e72656c6179446174612e72656c6179576f726b657272656c617943616c6c2072656c6179526571756573742e726571756573742e76616c6964556e74696c54696d65332e302e302d626574612e332b6f70656e67736e2e6875622e6972656c6179687562616464726573732066726f6d2c6164647265737320746f2c75696e743235362076616c75652c75696e74323536206761732c75696e74323536206e6f6e63652c627974657320646174612c75696e743235362076616c6964556e74696c54696d6572656c617943616c6c2072656c6179526571756573742e726571756573742e6e6f6e636572656c617943616c6c2072656c6179526571756573742e726571756573742e746f72656c617943616c6c2072656c6179526571756573742e726571756573742e67617372656c617943616c6c2072656c6179526571756573742e72656c6179446174612e7472616e73616374696f6e43616c6c646174614761735573656472656c617943616c6c2072656c6179526571756573742e72656c6179446174612e6d617846656550657247617372656c617943616c6c2072656c6179526571756573742e72656c6179446174612e636c69656e74496472656c617943616c6c2072656c6179526571756573742e72656c6179446174612e6d61785072696f7269747946656550657247617372656c617943616c6c2072656c6179526571756573742e726571756573742e76616c756572656c617943616c6c2072656c6179526571756573742e72656c6179446174612e7061796d61737465724461746152656c6179446174612875696e74323536206d61784665655065724761732c75696e74323536206d61785072696f726974794665655065724761732c75696e74323536207472616e73616374696f6e43616c6c64617461476173557365642c616464726573732072656c6179576f726b65722c61646472657373207061796d61737465722c6164647265737320666f727761726465722c6279746573207061796d6173746572446174612c75696e7432353620636c69656e7449642972656c617943616c6c2072656c6179526571756573742e726571756573742e6461746172656c617943616c6c2072656c6179526571756573742e72656c6179446174612e666f7277617264657272656c617943616c6c2072656c6179526571756573742e72656c6179446174612e7061796d617374657272656c617943616c6c2072656c6179526571756573742e726571756573742e66726f6da264697066735822122041494d4eb4299a7bd8ca18ee0373fafe82727ca3ef09c3fb66070ca8d4216eba64736f6c63430008070033", + "deployedBytecode": "0x6080604052600436106101f95760003560e01c80638e53548b1161010d578063ca64f9e7116100a0578063e6e22e121161006f578063e6e22e1214610664578063ebcd31ac14610684578063f2fde38b146106a4578063f3fef3a3146106c4578063f7908a74146106e457600080fd5b8063ca64f9e7146105b9578063d26152f9146105ec578063d904c7321461060c578063ddf737891461062e57600080fd5b8063af595dfc116100dc578063af595dfc14610528578063be7c76ad14610548578063c2da078614610581578063c7178230146105a157600080fd5b80638e53548b146104a75780639bcde3f3146104c7578063a6e61b60146104e7578063aa67c9191461051557600080fd5b80636bd50cef1161019057806372c1ab0c1161015f57806372c1ab0c146103f657806375dc7b4e146104165780638a09fb56146104495780638ac3b845146104695780638da5cb5b1461048957600080fd5b80636bd50cef146103595780636ca862e21461037b57806370a08231146103ab578063715018a6146103e157600080fd5b806345bdade7116101cc57806345bdade7146102a55780634f7de031146102ba57806351d85156146102dc57806359c4afc01461032357600080fd5b806301ffc9a7146101fe57806320ffd56d1461023357806339622167146102705780633c16e59a14610290575b600080fd5b34801561020a57600080fd5b5061021e61021936600461401c565b610717565b60405190151581526020015b60405180910390f35b34801561023f57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405190815260200161022a565b34801561027c57600080fd5b5061021e61028b366004613d66565b610769565b34801561029c57600080fd5b50600c54610262565b3480156102b157600080fd5b50610262610807565b3480156102c657600080fd5b506102da6102d5366004613d66565b61080f565b005b3480156102e857600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b03909116815260200161022a565b34801561032f57600080fd5b5061026261033e366004613d66565b6001600160a01b03166000908152600a602052604090205490565b34801561036557600080fd5b5061036e61096b565b60405161022a9190614a48565b34801561038757600080fd5b5061039b6103963660046141b6565b610a4c565b60405161022a9493929190614847565b3480156103b757600080fd5b506102626103c6366004613d66565b6001600160a01b03166000908152600b602052604090205490565b3480156103ed57600080fd5b506102da6118cf565b34801561040257600080fd5b506102da610411366004613e5c565b6118e3565b34801561042257600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061030b565b34801561045557600080fd5b506102da610464366004613f24565b611ba4565b34801561047557600080fd5b50610262610484366004614401565b611cfb565b34801561049557600080fd5b506000546001600160a01b031661030b565b3480156104b357600080fd5b506102626104c236600461441a565b611d30565b3480156104d357600080fd5b506102da6104e23660046142e2565b611dc6565b3480156104f357600080fd5b506105076105023660046140d1565b611f6c565b60405161022a9291906148bb565b6102da610523366004613d66565b6123f8565b34801561053457600080fd5b506102da610543366004614401565b6124d9565b34801561055457600080fd5b5061030b610563366004613d66565b6001600160a01b039081166000908152600960205260409020541690565b34801561058d57600080fd5b506102da61059c366004613de8565b61255c565b3480156105ad57600080fd5b50600c5442101561021e565b3480156105c557600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061030b565b3480156105f857600080fd5b506102da610607366004613d66565b61273f565b34801561061857600080fd5b506106216128bd565b60405161022a9190614875565b34801561063a57600080fd5b50610262610649366004613d66565b6001600160a01b031660009081526008602052604090205490565b34801561067057600080fd5b506102da61067f366004613d66565b6128dd565b34801561069057600080fd5b506102da61069f366004613daf565b612b80565b3480156106b057600080fd5b506102da6106bf366004613d66565b612dc8565b3480156106d057600080fd5b506102da6106df366004613d83565b612e41565b3480156106f057600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061030b565b60006001600160e01b0319821663e9fb30f760e01b148061074857506001600160e01b03198216630704183b60e11b145b8061076357506301ffc9a760e01b6001600160e01b03198316145b92915050565b604051633962216760e01b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063396221679060240160206040518083038186803b1580156107cf57600080fd5b505afa1580156107e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107639190613fbe565b60005a905090565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461088c5760405162461bcd60e51b815260206004820152601d60248201527f63616c6c6572206973206e6f742072656c61792072656769737472617200000060448201526064015b60405180910390fd5b610895816128dd565b6001600160a01b0381166000908152600a60205260409020546108ed5760405162461bcd60e51b815260206004820152601060248201526f6e6f2072656c617920776f726b65727360801b6044820152606401610883565b6040516346dcbf0b60e01b81526001600160a01b0382811660048301527f000000000000000000000000000000000000000000000000000000000000000016906346dcbf0b90602401600060405180830381600087803b15801561095057600080fd5b505af1158015610964573d6000803e3d6000fd5b5050505050565b6109d3604051806101200160405280600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b03168152602001600060ff16815260200160006001600160501b03168152602001600061ffff1681525090565b5060408051610120810182526001548152600254602082015260035491810191909152600454606082015260055460808201526006546001600160a01b03811660a0830152600160a01b810460ff1660c0830152600160a81b90046001600160501b031660e082015260075461ffff1661010082015290565b60008060006060610a5b613af1565b610a63610807565b6040820152610a738a8a8a612ee4565b6101e082015260408051808201909152601881527f72656c617943616c6c2072656c617952657175657374496400000000000000006020820152610ab690612f49565b610ac4816101e00151612f8c565b610afd60405180606001604052806023815260200161514760239139610aea8c80614b5f565b610af8906020810190613d66565b612fd1565b610b34604051806060016040528060218152602001614eb960219139610b238c80614b5f565b610af8906040810190602001613d66565b610b63604051806060016040528060248152602001614fc260249139610b5a8c80614b5f565b6040013561301a565b610b92604051806060016040528060228152602001614eda60229139610b898c80614b5f565b6060013561301a565b610bc1604051806060016040528060248152602001614e9560249139610bb88c80614b5f565b6080013561301a565b610bf06040518060600160405280602d8152602001614de5602d9139610be78c80614b5f565b60c0013561301a565b610c1f6040518060600160405280602d8152602001614f37602d9139610c1960208d018d614b75565b3561301a565b610c51604051806060016040528060358152602001614f8d60359139610c4860208d018d614b75565b6020013561301a565b610c7a6040518060600160405280603b8152602001614efc603b9139610b5a60208d018d614b75565b610cb46040518060600160405280602c8152602001614db9602c9139610ca360208d018d614b75565b610af8906080810190606001613d66565b610cee6040518060600160405280602a815260200161511d602a9139610cdd60208d018d614b75565b610af89060a0810190608001613d66565b610d286040518060600160405280602a81526020016150f3602a9139610d1760208d018d614b75565b610af89060c081019060a001613d66565b610d5a604051806060016040528060298152602001614f6460299139610d5160208d018d614b75565b60e0013561301a565b610d986040518060400160405280601d81526020017f72656c617943616c6c20646f6d61696e536570617261746f724e616d65000000815250612f49565b610dd78d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f4992505050565b610e0b6040518060400160405280601381526020017272656c617943616c6c207369676e617475726560681b815250612f49565b610e4a89898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061305f92505050565b610e816040518060400160405280601681526020017572656c617943616c6c20617070726f76616c4461746160501b815250612f49565b610ec087878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061305f92505050565b610ee16040518060600160405280602381526020016150d060239139612f49565b610f36610eee8b80614b5f565b610efc9060a0810190614b19565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061305f92505050565b610f576040518060600160405280602e8152602001614fe6602e9139612f49565b610f75610f6760208c018c614b75565b610efc9060c0810190614b19565b610fb46040518060400160405280601d81526020017f72656c617943616c6c206d6178416363657074616e63654275646765740000008152508c61301a565b600c544210610ff65760405162461bcd60e51b815260206004820152600e60248201526d1a1d588819195c1c9958d85d195960921b6044820152606401610883565b60046110028b80614b5f565b6110109060a0810190614b19565b9050101561101f576000611074565b61107461102c8b80614b5f565b61103a9060a0810190614b19565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506130a2915050565b6001600160e01b0319166020820152336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148015906110bb57503215155b156111cf578761110d5760405162461bcd60e51b815260206004820181905260248201527f6d697373696e67207369676e6174757265206f722062616420676174657761796044820152606401610883565b33321461115c5760405162461bcd60e51b815260206004820152601860248201527f72656c617920776f726b6572206d75737420626520454f4100000000000000006044820152606401610883565b61116960208b018b614b75565b61117a906080810190606001613d66565b6001600160a01b0316336001600160a01b0316146111cf5760405162461bcd60e51b81526020600482015260126024820152712737ba1030903934b3b43a103bb7b935b2b960711b6044820152606401610883565b321561126d57600960006111e660208d018d614b75565b6111f7906080810190606001613d66565b6001600160a01b039081168252602082019290925260400160002054166101c0820181905261125f5760405162461bcd60e51b81526020600482015260146024820152732ab735b737bbb7103932b630bc903bb7b935b2b960611b6044820152606401610883565b61126d816101c001516128dd565b61127c8b8b8360400151613112565b61010083015260a08201526112968d8d8c8c8c8c8c61339c565b60025460405a6112a790603f614cce565b6112b19190614cac565b6112bb9190614ced565b6101208201526112c9610807565b61014082015260035460045461012083015160408401516112ed60208f018f614b75565b604001356112fb9190614c94565b6113059190614c94565b61130f9190614c94565b6113199190614c94565b81610200018181525050306001600160a01b031681610120015163a6e61b6060e01b8f8f8e8e8e8e8e8a60a0015161134f610807565b8c610200015161135f9190614ced565b8c610100015160405160240161137e9a999897969594939291906148db565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516113bc919061466d565b60006040518083038160008787f1925050503d80600081146113fa576040519150601f19603f3d011682016040523d82523d6000602084013e6113ff565b606091505b5061022083015215158152611412610807565b8161014001516114229190614ced565b60e0820152610220810151805161144191602091810182019101614093565b8260c0018360800182905282600681111561145e5761145e614d61565b600681111561146f5761146f614d61565b90525050608081015151156114c0577fa1478a4242848419db824250a0dddc645dca0d6a9b12ab1fd79b00145a0ba98e8160c0015182608001516040516114b79291906148bb565b60405180910390a15b80516116225760028160c0015160068111156114de576114de614d61565b148061154d57506114f260208b018b614b75565b60a082015151611506916040013590614c94565b8160e001511115801561154d575060038160c00151600681111561152c5761152c614d61565b148061154d575060048160c00151600681111561154b5761154b614d61565b145b15611622576101e081015161156560208c018c614b75565b6115769060a0810190608001613d66565b6101c08301516001600160a01b0391821691167f0c47510cb900901afca7c9e926892582a36fd3bb7f908142ccf0fb4382a2b6846115b48e80614b5f565b6115c2906020810190613d66565b6115cc8f80614b5f565b6115dd906040810190602001613d66565b3387602001518860e0015189608001516040516115ff96959493929190614772565b60405180910390a46000808260c0015183608001519450945094509450506118c0565b60045461162d610807565b826040015161163c9190614ced565b61164960208d018d614b75565b604001356116579190614c94565b6116619190614c94565b610160820181905261167a906104c260208d018d614b75565b935061168584611cfb565b61018082015283600b600061169d60208e018e614b75565b6116ae9060a0810190608001613d66565b6001600160a01b03166001600160a01b03168152602001908152602001600020546116d99190614ced565b600b60006116ea60208e018e614b75565b6116fb9060a0810190608001613d66565b6001600160a01b031681526020810191909152604001600020556101808101516117259085614ced565b6101c08201516001600160a01b03166000908152600b602052604090205461174d9190614c94565b6101c08201516001600160a01b03166000908152600b6020526040902055610180810151156117bd576101808101516006546001600160a01b03166000908152600b60205260409020546117a19190614c94565b6006546001600160a01b03166000908152600b60205260409020555b60006117c98b80614b5f565b6117d7906020810190613d66565b905060006117e58c80614b5f565b6117f6906040810190602001613d66565b9050600061180760208e018e614b75565b6118189060a0810190608001613d66565b9050836101e00151336001600160a01b0316856101c001516001600160a01b03167fd51ac07012398c2059ec53c6005fa8639657917bd2dbd72bc489a3c0eaaa7f168686868a602001518b60c001518f60405161187a96959493929190614724565b60405180910390a4505050326118a35760c08101516080909101516001955090925090506118c0565b60c001516040805160208101909152600081526001955090925090505b98509850985098945050505050565b6118d7613476565b6118e160006134d0565b565b3360005b8251811015611b9e576119886040518060400160405280601981526020017f77697468647261774d756c7469706c6520257320257320257300000000000000815250600b6000856001600160a01b03166001600160a01b031681526020019081526020016000205486848151811061196157611961614d77565b602002602001015186858151811061197b5761197b614d77565b6020026020010151613520565b6001600160a01b0382166000908152600b602052604090205483518490839081106119b5576119b5614d77565b6020026020010151811015611a015760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610883565b838281518110611a1357611a13614d77565b602002602001015181611a269190614ced565b6001600160a01b0384166000908152600b60205260408120919091558551869084908110611a5657611a56614d77565b60200260200101516001600160a01b0316858481518110611a7957611a79614d77565b602002602001015160405160006040518083038185875af1925050503d8060008114611ac1576040519150601f19603f3d011682016040523d82523d6000602084013e611ac6565b606091505b5050905080611b0a5760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610883565b858381518110611b1c57611b1c614d77565b60200260200101516001600160a01b0316846001600160a01b03167fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb878681518110611b6a57611b6a614d77565b6020026020010151604051611b8191815260200190565b60405180910390a350508080611b9690614d30565b9150506118e7565b50505050565b611bac613476565b8051825114611bfd5760405162461bcd60e51b815260206004820152601e60248201527f7365744d696e696d756d5374616b65733a2077726f6e67206c656e67746800006044820152606401610883565b60005b8251811015611cf657818181518110611c1b57611c1b614d77565b602002602001015160086000858481518110611c3957611c39614d77565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055507ffb7510fe755f485459ee8ed619d4a0addc092c230ff47e760a62aeba78ebb9e3838281518110611c9857611c98614d77565b6020026020010151838381518110611cb257611cb2614d77565b6020026020010151604051611cdc9291906001600160a01b03929092168252602082015260400190565b60405180910390a180611cee81614d30565b915050611c00565b505050565b600654600090600160a01b900460ff16611d1757506000919050565b600654606490600160a01b900460ff1683020492915050565b600080823560208401351415611d4857506000611d4b565b50485b6000611d678435611d623a81602089013587614c94565b613569565b600754909150606490611d7e9061ffff1682614c6e565b61ffff16611d8c8388614cce565b611d969190614cce565b611da09190614cac565b600654611dbd9190600160a81b90046001600160501b0316614c94565b95945050505050565b611dce613476565b60648160c0015160ff1610611e185760405162461bcd60e51b815260206004820152601060248201526f0c8caec40cccaca40e8dede40d0d2ced60831b6044820152606401610883565b8051600190815560208201516002556040808301516003556060830151600455608083015160055560a08301516006805460c086015160e08701516001600160501b0316600160a81b0269ffffffffffffffffffff60a81b1960ff909216600160a01b026001600160a81b03199093166001600160a01b039095169490941791909117169190911790556101008301516007805461ffff90921661ffff19909216919091179055517f4812ada68f7c2cdc9f4a4a09e157ea6b924e0ef40a4fa7aa074fa8f70b1e724791611f6191815481526001820154602082015260028201546040820152600382015460608201526004820154608082015260058201546001600160a01b03811660a08084019190915260ff9082901c1660c08301526001600160501b0360a89190911c1660e082015260069091015461ffff166101008201526101200190565b60405180910390a150565b60006060611fc6604051806101200160405280600081526020016000815260200160008152602001600080191681526020016000151581526020016060815260200160608152602001606081526020016000151581525090565b611fce610807565b81525a611fdb9086614ced565b602082015233301461202f5760405162461bcd60e51b815260206004820152601a60248201527f4d7573742062652063616c6c65642062792052656c61794875620000000000006044820152606401610883565b600b600061204060208e018e614b75565b6120519060a0810190608001613d66565b6001600160a01b0316815260208101919091526040908101600020548282015251622f977560e21b90612092908d908d908d908d908d908b90602401614aca565b60408051601f19818403018152919052602080820180516001600160e01b03166001600160e01b03199094169390931790925260e08301526000906060906120dc908e018e614b75565b6120ed9060a0810190608001613d66565b6001600160a01b031688602001358460e0015160405161210d919061466d565b60006040518083038160008787f1925050503d806000811461214b576040519150601f19603f3d011682016040523d82523d6000602084013e612150565b606091505b5090925090508161216f5761216481613581565b61216f60028261358d565b808060200190518101906121839190614046565b8460c001856101000182151515158152508290525050505060006121ed8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8d6135c6565b60a08501521515608084015290508061220f5761220f60038360a0015161358d565b816101000151801561222357508160800151155b156122375761223760048360a0015161358d565b506376fa01c360e01b8160c001518260800151612252610807565b845161225e9190614ced565b846020015161226d9190614c94565b8e806020019061227d9190614b75565b6040516024016122909493929190614888565b60408051601f19818403018152919052602080820180516001600160e01b03166001600160e01b03199094169390931790925260e083015260009081906122d9908e018e614b75565b6122ea9060a0810190608001613d66565b6001600160a01b031688604001358460e0015160405161230a919061466d565b60006040518083038160008787f1925050503d8060008114612348576040519150601f19603f3d011682016040523d82523d6000602084013e61234d565b606091505b5091509150816123625761236260058261358d565b50506040810151600b600061237a60208f018f614b75565b61238b9060a0810190608001613d66565b6001600160a01b03166001600160a01b031681526020019081526020016000205410156123cc576123cc60066040518060200160405280600081525061358d565b80608001516123dc5760016123df565b60005b8160a0015192509250509a509a98505050505050505050565b6124126001600160a01b0382166370d596f560e11b6137ac565b61245e5760405162461bcd60e51b815260206004820181905260248201527f746172676574206973206e6f7420612076616c696420495061796d61737465726044820152606401610883565b6001600160a01b0381166000908152600b60205260409020543490612484908290614c94565b6001600160a01b0383166000818152600b6020908152604091829020939093555183815233927f8752a472e571a816aea92eec8dae9baf628e840f4929fbcc2d155e6233ff68a7910160405180910390a35050565b6124e1613476565b600c5442106125275760405162461bcd60e51b8152602060048201526012602482015271105b1c9958591e4819195c1c9958d85d195960721b6044820152606401610883565b600c8190556040518181527f1c0aa0c666483fbf0cf795d9d646ea3552d1e3008162ba9ab1d6d6dfd8c6ec6b90602001611f61565b336000818152600a6020526040812054612577908490614c94565b6001600160a01b0383166000908152600a602052604090208190556001549091508111156125da5760405162461bcd60e51b815260206004820152601060248201526f746f6f206d616e7920776f726b65727360801b6044820152606401610883565b6125e3826128dd565b60005b838110156126f357600060098187878581811061260557612605614d77565b905060200201602081019061261a9190613d66565b6001600160a01b03908116825260208201929092526040016000205416146126845760405162461bcd60e51b815260206004820152601960248201527f7468697320776f726b6572206861732061206d616e61676572000000000000006044820152606401610883565b826009600087878581811061269b5761269b614d77565b90506020020160208101906126b09190613d66565b6001600160a01b039081168252602082019290925260400160002080546001600160a01b03191692909116919091179055806126eb81614d30565b9150506125e6565b50816001600160a01b03167febf4a9bffb39f7c5dbf3f65540183b9381ae226ac3d0a45b4cad484713bd4a28858584604051612731939291906147f1565b60405180910390a250505050565b612747613476565b604051633962216760e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063396221679060240160206040518083038186803b1580156127a857600080fd5b505afa1580156127bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e09190613fbe565b61282c5760405162461bcd60e51b815260206004820181905260248201527f72656c617920736572766572206e6f74206573636865617461626c65207965746044820152606401610883565b6001600160a01b038082166000908152600b60205260408082208054908390556006549093168252902054612862908290614c94565b6006546001600160a01b039081166000908152600b60209081526040918290209390935551838152908416917f3fb672a061b9c3ab083062a9a8ff532d341e5fa42145b91f3922a711ae135659910160405180910390a25050565b6060604051806060016040528060228152602001614e1260229139905090565b60405163c345315360e01b81526001600160a01b03828116600483015260009182917f0000000000000000000000000000000000000000000000000000000000000000169063c3453153906024016101006040518083038186803b15801561294457600080fd5b505afa158015612958573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061297c9190614375565b60a0820180516001600160a01b03908116600090815260086020526040902054915193955091935091166129ed5760405162461bcd60e51b81526020600482015260186024820152771c995b185e481b585b9859d95c881b9bdd081cdd185ad95960421b6044820152606401610883565b8251811115612a3e5760405162461bcd60e51b815260206004820152601960248201527f7374616b6520616d6f756e7420697320746f6f20736d616c6c000000000000006044820152606401610883565b80612a8b5760405162461bcd60e51b815260206004820152601f60248201527f7374616b696e67207468697320746f6b656e20697320666f7262696464656e006044820152606401610883565b60055460208401511015612ae15760405162461bcd60e51b815260206004820152601a60248201527f756e7374616b652064656c617920697320746f6f20736d616c6c0000000000006044820152606401610883565b604083015115612b335760405162461bcd60e51b815260206004820152601860248201527f7374616b6520686173206265656e2077697468647261776e00000000000000006044820152606401610883565b81611b9e5760405162461bcd60e51b815260206004820181905260248201527f7468697320687562206973206e6f7420617574686f72697a656420627920534d6044820152606401610883565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614612be85760405162461bcd60e51b815260206004820152600d60248201526c2737ba103832b730b634bd32b960991b6044820152606401610883565b6001600160a01b038083166000908152600960205260409020541680612c475760405162461bcd60e51b81526020600482015260146024820152732ab735b737bbb7103932b630bc903bb7b935b2b960611b6044820152606401610883565b60405163c345315360e01b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063c3453153906024016101006040518083038186803b158015612cae57600080fd5b505afa158015612cc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce69190614375565b508051909150612d335760405162461bcd60e51b81526020600482015260186024820152771c995b185e481b585b9859d95c881b9bdd081cdd185ad95960421b6044820152606401610883565b805160405163026822bd60e21b81526001600160a01b038481166004830152858116602483015260448201929092527f0000000000000000000000000000000000000000000000000000000000000000909116906309a08af490606401600060405180830381600087803b158015612daa57600080fd5b505af1158015612dbe573d6000803e3d6000fd5b5050505050505050565b612dd0613476565b6001600160a01b038116612e355760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610883565b612e3e816134d0565b50565b6040805160018082528183019092526000916020808301908036833750506040805160018082528183019092529293506000929150602080830190803683370190505090508282600081518110612e9a57612e9a614d77565b6020026020010181815250508381600081518110612eba57612eba614d77565b60200260200101906001600160a01b031690816001600160a01b031681525050611b9e81836118e3565b60006001600160e01b03612ef88580614b5f565b612f06906020810190613d66565b612f108680614b5f565b608001358585604051602001612f2994939291906147c9565b604051602081830303815290604052805190602001201690509392505050565b612e3e81604051602401612f5d9190614875565b60408051601f198184030181529190526020810180516001600160e01b031663104c13eb60e21b1790526137c8565b612e3e81604051602401612fa291815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166327b7cf8560e01b1790526137c8565b6130168282604051602401612fe7929190614971565b60408051601f198184030181529190526020810180516001600160e01b031663319af33360e01b1790526137c8565b5050565b613016828260405160240161303092919061499b565b60408051601f198184030181529190526020810180516001600160e01b0316632d839cb360e21b1790526137c8565b612e3e816040516024016130739190614875565b60408051601f198184030181529190526020810180516001600160e01b03166305f3bfab60e11b1790526137c8565b60006130af826004614c94565b835110156130ff5760405162461bcd60e51b815260206004820152601a60248201527f726561644279746573343a206461746120746f6f2073686f72740000000000006044820152606401610883565b5001602001516001600160e01b03191690565b61313d6040518060800160405280600081526020016000815260200160008152602001600081525090565b600061314c6020850185614b75565b61315d9060a0810190608001613d66565b6001600160a01b031663b039a88f61c3506040518263ffffffff1660e01b815260040160806040518083038187803b15801561319857600080fd5b5086fa1580156131ac573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906131d1919061427d565b60608101519092503611156132285760405162461bcd60e51b815260206004820152601760248201527f6d73672e64617461206578636565646564206c696d69740000000000000000006044820152606401610883565b81518510156132795760405162461bcd60e51b815260206004820152601a60248201527f616363657074616e63652062756467657420746f6f20686967680000000000006044820152606401610883565b6020820151825110156132ce5760405162461bcd60e51b815260206004820152601960248201527f616363657074616e63652062756467657420746f6f206c6f77000000000000006044820152606401610883565b826132dc6020860186614b75565b604001356132ea9190614c94565b905060006132ff826104c26020880188614b75565b9050600b60006133126020880188614b75565b6133239060a0810190608001613d66565b6001600160a01b03166001600160a01b03168152602001908152602001600020548111156133935760405162461bcd60e51b815260206004820152601960248201527f5061796d61737465722062616c616e636520746f6f206c6f77000000000000006044820152606401610883565b50935093915050565b60006133c16133ae6020880188614b75565b6133bc9060c0810190614b19565b6137d1565b6133dc6133ce8880614b5f565b6133bc9060a0810190614b19565b6133e685856137d1565b6133f088886137d1565b6133fa8c8c6137d1565b613406906102c4614c94565b6134109190614c94565b61341a9190614c94565b6134249190614c94565b61342e9190614c94565b9050368114612dbe5760405162461bcd60e51b81526020600482015260146024820152736578747261206d73672e6461746120627974657360601b6044820152606401610883565b6000546001600160a01b031633146118e15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610883565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611b9e8484848460405160240161353a94939291906149bd565b60408051601f198184030181529190526020810180516001600160e01b03166327827ee360e11b1790526137c8565b6000818310613578578161357a565b825b9392505050565b612e3e816104006137f7565b600082826040516020016135a29291906148bb565b60405160208183030381529060405290506135bc81613581565b8051602082018181fd5b600080606060006135d687613804565b90506000613601896135eb60208b018b614b75565b6135fc9060c081019060a001613d66565b613843565b90506136106020890189614b75565b6136219060c081019060a001613d66565b6001600160a01b031663e024dc7f60e01b61363c8a80614b5f565b836040518060400160405280600c81526020016b14995b185e54995c5d595cdd60a21b8152506040518060a0016040528060618152602001614e34606191396040518060e0016040528060bc815260200161501460bc91396040516020016136a491906146e8565b60408051601f19818403018152908290526136c3939291602001614689565b60405160208183030381529060405280519060200120868c8c6040516024016136f1969594939291906149f5565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161372f919061466d565b6000604051808303816000865af19150503d806000811461376c576040519150601f19603f3d011682016040523d82523d6000602084013e613771565b606091505b509095509250841561379757828060200190518101906137919190613fd9565b90945092505b6137a083613581565b50509450945094915050565b60006137b783613896565b801561357a575061357a83836138c9565b612e3e81613952565b60006137e0601f600019614ced565b6137eb83601f614c94565b61357a91166020614c94565b8082511115613016579052565b606061381b6138166020840184614b75565b613973565b60405160200161382d91815260200190565b6040516020818303038152906040529050919050565b600061357a6040518060800160405280858152602001604051806040016040528060018152602001603360f81b815250815260200161387f4690565b8152602001846001600160a01b0316815250613a71565b60006138a9826301ffc9a760e01b6138c9565b801561076357506138c2826001600160e01b03196138c9565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d9150600051905082801561393b575060208210155b80156139475750600081115b979650505050505050565b60006a636f6e736f6c652e6c6f679050600080835160208501845afa505050565b60006040518060e0016040528060bc815260200161501460bc913980516020918201209083359084013560408501356139b26080870160608801613d66565b6139c260a0880160808901613d66565b6139d260c0890160a08a01613d66565b6139df60c08a018a614b19565b6040516139ed92919061465d565b604051908190038120613a54989796959493929160e08c0135906020019889526020890197909752604088019590955260608701939093526001600160a01b039182166080870152811660a08601521660c084015260e08301526101008201526101200190565b604051602081830303815290604052805190602001209050919050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82600001518051906020012083602001518051906020012084604001518560600151604051602001613a549594939291909485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b60405180610240016040528060001515815260200160006001600160e01b0319168152602001600081526020016060815260200160608152602001613b576040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016060815260200160006001600160a01b031681526020016000801916815260200160008152602001606081525090565b8035613bc881614da3565b919050565b600082601f830112613bde57600080fd5b81356020613bf3613bee83614c06565b614bd6565b80838252828201915082860187848660051b8901011115613c1357600080fd5b60005b85811015613c3257813584529284019290840190600101613c16565b5090979650505050505050565b80518015158114613bc857600080fd5b60008083601f840112613c6157600080fd5b5081356001600160401b03811115613c7857600080fd5b602083019150836020828501011115613c9057600080fd5b9250929050565b600082601f830112613ca857600080fd5b81516001600160401b03811115613cc157613cc1614d8d565b613cd4601f8201601f1916602001614bd6565b818152846020838601011115613ce957600080fd5b613cfa826020830160208701614d04565b949350505050565b600060808284031215613d1457600080fd5b50919050565b600060408284031215613d1457600080fd5b803561ffff81168114613bc857600080fd5b803560ff81168114613bc857600080fd5b80356001600160501b0381168114613bc857600080fd5b600060208284031215613d7857600080fd5b813561357a81614da3565b60008060408385031215613d9657600080fd5b8235613da181614da3565b946020939093013593505050565b60008060408385031215613dc257600080fd5b8235613dcd81614da3565b91506020830135613ddd81614da3565b809150509250929050565b60008060208385031215613dfb57600080fd5b82356001600160401b0380821115613e1257600080fd5b818501915085601f830112613e2657600080fd5b813581811115613e3557600080fd5b8660208260051b8501011115613e4a57600080fd5b60209290920196919550909350505050565b60008060408385031215613e6f57600080fd5b82356001600160401b0380821115613e8657600080fd5b818501915085601f830112613e9a57600080fd5b81356020613eaa613bee83614c06565b8083825282820191508286018a848660051b8901011115613eca57600080fd5b600096505b84871015613ef6578035613ee281614da3565b835260019690960195918301918301613ecf565b5096505086013592505080821115613f0d57600080fd5b50613f1a85828601613bcd565b9150509250929050565b60008060408385031215613f3757600080fd5b82356001600160401b0380821115613f4e57600080fd5b818501915085601f830112613f6257600080fd5b81356020613f72613bee83614c06565b8083825282820191508286018a848660051b8901011115613f9257600080fd5b600096505b84871015613ef6578035613faa81614da3565b835260019690960195918301918301613f97565b600060208284031215613fd057600080fd5b61357a82613c3f565b60008060408385031215613fec57600080fd5b613ff583613c3f565b915060208301516001600160401b0381111561401057600080fd5b613f1a85828601613c97565b60006020828403121561402e57600080fd5b81356001600160e01b03198116811461357a57600080fd5b6000806040838503121561405957600080fd5b82516001600160401b0381111561406f57600080fd5b61407b85828601613c97565b92505061408a60208401613c3f565b90509250929050565b600080604083850312156140a657600080fd5b8251600781106140b557600080fd5b60208401519092506001600160401b0381111561401057600080fd5b6000806000806000806000806000806101408b8d0312156140f157600080fd5b8a356001600160401b038082111561410857600080fd5b6141148e838f01613c4f565b909c509a5060208d013591508082111561412d57600080fd5b6141398e838f01613d1a565b995060408d013591508082111561414f57600080fd5b61415b8e838f01613c4f565b909950975060608d013591508082111561417457600080fd5b506141818d828e01613c4f565b909650945061419590508c60808d01613d02565b92506101008b013591506101208b013590509295989b9194979a5092959850565b60008060008060008060008060a0898b0312156141d257600080fd5b88356001600160401b03808211156141e957600080fd5b6141f58c838d01613c4f565b909a50985060208b0135975060408b013591508082111561421557600080fd5b6142218c838d01613d1a565b965060608b013591508082111561423757600080fd5b6142438c838d01613c4f565b909650945060808b013591508082111561425c57600080fd5b506142698b828c01613c4f565b999c989b5096995094979396929594505050565b60006080828403121561428f57600080fd5b604051608081018181106001600160401b03821117156142b1576142b1614d8d565b8060405250825181526020830151602082015260408301516040820152606083015160608201528091505092915050565b600061012082840312156142f557600080fd5b6142fd614b8b565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261433560a08401613bbd565b60a082015261434660c08401613d3e565b60c082015261435760e08401613d4f565b60e082015261010061436a818501613d2c565b908201529392505050565b60008082840361010081121561438a57600080fd5b60e081121561439857600080fd5b506143a1614bb4565b835181526020840151602082015260408401516040820152606084015160608201526080840151608082015260a08401516143db81614da3565b60a082015260c08401516143ee81614da3565b60c0820152915061408a60e08401613c3f565b60006020828403121561441357600080fd5b5035919050565b6000806040838503121561442d57600080fd5b8235915060208301356001600160401b0381111561444a57600080fd5b83016101008186031215613ddd57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000815180845261449e816020860160208601614d04565b601f01601f19169290920160200192915050565b600781106144d057634e487b7160e01b600052602160045260246000fd5b9052565b600081356144e181614da3565b6001600160a01b0390811684526020830135906144fd82614da3565b16602084015260408281013590840152606080830135908401526080808301359084015261452e60a0830183614c29565b60e060a086015261454360e08601828461445d565b91505060c083013560c08501528091505092915050565b6000610100823584526020830135602085015260408301356040850152606083013561458581614da3565b6001600160a01b0390811660608601526080840135906145a482614da3565b16608085015260a08301356145b881614da3565b6001600160a01b031660a08501526145d360c0840184614c29565b8260c08701526145e6838701828461445d565b9250505060e083013560e08501528091505092915050565b6000813582360360de198101821261461557600080fd5b60408552614628604086018584016144d4565b9150602084013560fe198201811261463f57600080fd5b85830360208701526146538386830161455a565b9695505050505050565b8183823760009101908152919050565b6000825161467f818460208701614d04565b9190910192915050565b6000845161469b818460208901614d04565b600560fb1b90830190815284516146b9816001840160208901614d04565b600b60fa1b6001929091019182015283516146db816002840160208801614d04565b0160020195945050505050565b7352656c6179446174612072656c6179446174612960601b815260008251614717816014850160208701614d04565b9190910160140192915050565b6001600160a01b0387811682528681166020830152851660408201526001600160e01b03198416606082015260c0810161476160808301856144b2565b8260a0830152979650505050505050565b6001600160a01b0387811682528681166020830152851660408201526001600160e01b0319841660608201526080810183905260c060a082018190526000906147bd90830184614486565b98975050505050505050565b60018060a01b038516815283602082015260606040820152600061465360608301848661445d565b6040808252810183905260008460608301825b8681101561483457823561481781614da3565b6001600160a01b0316825260209283019290910190600101614804565b5060209390930193909352509392505050565b841515815283602082015261485f60408201846144b2565b6080606082015260006146536080830184614486565b60208152600061357a6020830184614486565b60808152600061489b6080830187614486565b85151560208401528460408401528281036060840152613947818561455a565b6148c581846144b2565b604060208201526000613cfa6040830184614486565b60006101408083526148f08184018d8f61445d565b90508281036020840152614904818c6145fe565b90508281036040840152614919818a8c61445d565b9050828103606084015261492e81888a61445d565b86516080850152602087015160a0850152604087015160c085015260609096015160e0840152505061010081019290925261012090910152979650505050505050565b6040815260006149846040830185614486565b905060018060a01b03831660208301529392505050565b6040815260006149ae6040830185614486565b90508260208301529392505050565b6080815260006149d06080830187614486565b6020830195909552506001600160a01b03929092166040830152606090910152919050565b60a081526000614a0860a08301896144d4565b8760208401528660408401528281036060840152614a268187614486565b90508281036080840152614a3b81858761445d565b9998505050505050505050565b600061012082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260018060a01b0360a08401511660a083015260ff60c08401511660c083015260e0830151614ab660e08401826001600160501b03169052565b506101009283015161ffff16919092015290565b608081526000614add60808301896145fe565b8281036020840152614af081888a61445d565b90508281036040840152614b0581868861445d565b915050826060830152979650505050505050565b6000808335601e19843603018112614b3057600080fd5b8301803591506001600160401b03821115614b4a57600080fd5b602001915036819003821315613c9057600080fd5b6000823560de1983360301811261467f57600080fd5b6000823560fe1983360301811261467f57600080fd5b60405161012081016001600160401b0381118282101715614bae57614bae614d8d565b60405290565b60405160e081016001600160401b0381118282101715614bae57614bae614d8d565b604051601f8201601f191681016001600160401b0381118282101715614bfe57614bfe614d8d565b604052919050565b60006001600160401b03821115614c1f57614c1f614d8d565b5060051b60200190565b6000808335601e19843603018112614c4057600080fd5b83016020810192503590506001600160401b03811115614c5f57600080fd5b803603831315613c9057600080fd5b600061ffff808316818516808303821115614c8b57614c8b614d4b565b01949350505050565b60008219821115614ca757614ca7614d4b565b500190565b600082614cc957634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615614ce857614ce8614d4b565b500290565b600082821015614cff57614cff614d4b565b500390565b60005b83811015614d1f578181015183820152602001614d07565b83811115611b9e5750506000910152565b6000600019821415614d4457614d44614d4b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114612e3e57600080fdfe72656c617943616c6c2072656c6179526571756573742e72656c6179446174612e72656c6179576f726b657272656c617943616c6c2072656c6179526571756573742e726571756573742e76616c6964556e74696c54696d65332e302e302d626574612e332b6f70656e67736e2e6875622e6972656c6179687562616464726573732066726f6d2c6164647265737320746f2c75696e743235362076616c75652c75696e74323536206761732c75696e74323536206e6f6e63652c627974657320646174612c75696e743235362076616c6964556e74696c54696d6572656c617943616c6c2072656c6179526571756573742e726571756573742e6e6f6e636572656c617943616c6c2072656c6179526571756573742e726571756573742e746f72656c617943616c6c2072656c6179526571756573742e726571756573742e67617372656c617943616c6c2072656c6179526571756573742e72656c6179446174612e7472616e73616374696f6e43616c6c646174614761735573656472656c617943616c6c2072656c6179526571756573742e72656c6179446174612e6d617846656550657247617372656c617943616c6c2072656c6179526571756573742e72656c6179446174612e636c69656e74496472656c617943616c6c2072656c6179526571756573742e72656c6179446174612e6d61785072696f7269747946656550657247617372656c617943616c6c2072656c6179526571756573742e726571756573742e76616c756572656c617943616c6c2072656c6179526571756573742e72656c6179446174612e7061796d61737465724461746152656c6179446174612875696e74323536206d61784665655065724761732c75696e74323536206d61785072696f726974794665655065724761732c75696e74323536207472616e73616374696f6e43616c6c64617461476173557365642c616464726573732072656c6179576f726b65722c61646472657373207061796d61737465722c6164647265737320666f727761726465722c6279746573207061796d6173746572446174612c75696e7432353620636c69656e7449642972656c617943616c6c2072656c6179526571756573742e726571756573742e6461746172656c617943616c6c2072656c6179526571756573742e72656c6179446174612e666f7277617264657272656c617943616c6c2072656c6179526571756573742e72656c6179446174612e7061796d617374657272656c617943616c6c2072656c6179526571756573742e726571756573742e66726f6da264697066735822122041494d4eb4299a7bd8ca18ee0373fafe82727ca3ef09c3fb66070ca8d4216eba64736f6c63430008070033", + "devdoc": { + "kind": "dev", + "methods": { + "aggregateGasleft()": { + "returns": { + "_0": "A total measurable amount of gas left to current execution. Same as 'gasleft()' for pure EVMs." + } + }, + "balanceOf(address)": { + "returns": { + "_0": "An account's balance. It can be either a deposit of a `Paymaster`, or a revenue of a Relay Manager." + } + }, + "calculateCharge(uint256,(uint256,uint256,uint256,address,address,address,bytes,uint256))": { + "params": { + "gasUsed": "An amount of gas used by the transaction.", + "relayData": "The details of a transaction signed by the sender." + }, + "returns": { + "_0": "The calculated charge, in wei." + } + }, + "calculateDevCharge(uint256)": { + "params": { + "charge": "The amount of Ether in wei the Paymaster will be charged for this transaction." + }, + "returns": { + "_0": "The calculated devFee, in wei." + } + }, + "deprecateHub(uint256)": { + "params": { + "_deprecationTime": "The timestamp in seconds after which the `RelayHub` stops serving transactions." + } + }, + "getBatchGateway()": { + "returns": { + "_0": "The `BatchGateway` address for this `RelayHub`." + } + }, + "getConfiguration()": { + "returns": { + "_0": "The configuration of the `RelayHub`." + } + }, + "getCreationBlock()": { + "returns": { + "_0": "The block number in which the contract has been deployed." + } + }, + "getDeprecationTime()": { + "returns": { + "_0": "The timestamp from which the hub no longer allows relaying calls." + } + }, + "getMinimumStakePerToken(address)": { + "params": { + "token": "An address of an ERC-20 compatible tokens." + }, + "returns": { + "_0": "The minimum amount of a given `token` that needs to be staked so that the Relay Manager is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking." + } + }, + "getPenalizer()": { + "returns": { + "_0": "The `Penalizer` address for this `RelayHub`." + } + }, + "getRelayRegistrar()": { + "returns": { + "_0": "The `RelayRegistrar` address for this `RelayHub`." + } + }, + "getStakeManager()": { + "returns": { + "_0": "The `StakeManager` address for this `RelayHub`." + } + }, + "getWorkerCount(address)": { + "params": { + "manager": "An address of the Relay Manager." + }, + "returns": { + "_0": "The count of Relay Workers associated with this Relay Manager." + } + }, + "getWorkerManager(address)": { + "params": { + "worker": "An address of the Relay Worker." + }, + "returns": { + "_0": "The address of its Relay Manager." + } + }, + "isDeprecated()": { + "returns": { + "_0": "`true` if the `RelayHub` is deprecated, `false` it it is not deprecated and can serve transactions." + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "penalize(address,address)": { + "params": { + "beneficiary": "The address that called the `Penalizer` and will receive a reward for it.", + "relayWorker": "The address of the Relay Worker that committed a penalizable offense." + } + }, + "relayCall(string,uint256,((address,address,uint256,uint256,uint256,bytes,uint256),(uint256,uint256,uint256,address,address,address,bytes,uint256)),bytes,bytes)": { + "params": { + "approvalData": "The dapp-specific data forwarded to the `Paymaster`'s `preRelayedCall` method. This value is **not** verified by the `RelayHub` in any way. As an example, it can be used to pass some kind of a third-party signature to the `Paymaster` for verification. Emits a `TransactionRelayed` event regardless of whether the transaction succeeded or failed.", + "domainSeparatorName": "The name of the Domain Separator used to verify the EIP-712 signature", + "maxAcceptanceBudget": "The maximum valid value for `paymaster.getGasLimits().acceptanceBudget` to return.", + "relayRequest": "All details of the requested relayed call.", + "signature": "The client's EIP-712 signature over the `relayRequest` struct." + } + }, + "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." + }, + "setConfiguration((uint256,uint256,uint256,uint256,uint256,address,uint8,uint80,uint16))": { + "params": { + "_config": "The new configuration." + } + }, + "setMinimumStakes(address[],uint256[])": { + "params": { + "minimumStake": "An array of minimal amounts necessary for a corresponding token, in wei.", + "token": "An array of addresses of ERC-20 compatible tokens." + } + }, + "supportsInterface(bytes4)": { + "details": "Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + }, + "versionHub()": { + "returns": { + "_0": "a SemVer-compliant version of the `RelayHub` contract." + } + } + }, + "title": "The RelayHub Implementation", + "version": 1 + }, + "userdoc": { + "events": { + "AbandonedRelayManagerBalanceEscheated(address,uint256)": { + "notice": "This event is emitted in case a `relayManager` has been deemed \"abandoned\" for being unresponsive for a prolonged period of time.This event means the entire balance of the relay has been transferred to the `devAddress`." + }, + "Deposited(address,address,uint256)": { + "notice": "Emitted when `depositFor` is called, including the amount and account that was funded." + }, + "HubDeprecated(uint256)": { + "notice": "This event is emitted in case this `RelayHub` is deprecated and will stop serving transactions soon." + }, + "RelayHubConfigured((uint256,uint256,uint256,uint256,uint256,address,uint8,uint80,uint16))": { + "notice": "Emitted when a configuration of the `RelayHub` is changed" + }, + "RelayWorkersAdded(address,address[],uint256)": { + "notice": "Emitted when relays are added by a relayManager" + }, + "StakingTokenDataChanged(address,uint256)": { + "notice": "Emitted for each token configured for staking in setMinimumStakes" + }, + "TransactionRejectedByPaymaster(address,address,bytes32,address,address,address,bytes4,uint256,bytes)": { + "notice": "Emitted when an attempt to relay a call fails and the `Paymaster` does not accept the transaction. The actual relayed call was not executed, and the recipient not charged." + }, + "TransactionRelayed(address,address,bytes32,address,address,address,bytes4,uint8,uint256)": { + "notice": "Emitted when a transaction is relayed. Note that the actual internal function call might be reverted. The reason for a revert will be indicated in the `status` field of a corresponding `RelayCallStatus` value.`charge` is the Ether value deducted from the `Paymaster` balance. The amount added to the `relayManager` balance will be lower if there is an activated `devFee` in the `config`." + }, + "TransactionResult(uint8,bytes)": { + "notice": "This event is emitted in case the internal function returns a value or reverts with a revert string." + }, + "Withdrawn(address,address,uint256)": { + "notice": "Emitted when an account withdraws funds from the `RelayHub`." + } + }, + "kind": "user", + "methods": { + "addRelayWorkers(address[])": { + "notice": "Add new worker addresses controlled by the sender who must be a staked Relay Manager address. Emits a `RelayWorkersAdded` event. This function can be called multiple times, emitting new events." + }, + "calculateCharge(uint256,(uint256,uint256,uint256,address,address,address,bytes,uint256))": { + "notice": "The fee is expressed as a base fee in wei plus percentage of the actual charge. For example, a value '40' stands for a 40% fee, so the recipient will be charged for 1.4 times the spent amount." + }, + "calculateDevCharge(uint256)": { + "notice": "The fee is expressed as a percentage of the actual charge. For example, a value '40' stands for a 40% fee, so the Relay Manager will only get 60% of the `charge`." + }, + "depositFor(address)": { + "notice": "Deposits ether for a `Paymaster`, so that it can and pay for relayed transactions. :warning: **Warning** :warning: Unused balance can only be withdrawn by the holder itself, by calling `withdraw`. Emits a `Deposited` event." + }, + "deprecateHub(uint256)": { + "notice": "Deprecate hub by reverting all incoming `relayCall()` calls starting from a given timestamp" + }, + "escheatAbandonedRelayBalance(address)": { + "notice": "@param relayManager" + }, + "innerRelayCall(string,((address,address,uint256,uint256,uint256,bytes,uint256),(uint256,uint256,uint256,address,address,address,bytes,uint256)),bytes,bytes,(uint256,uint256,uint256,uint256),uint256,uint256)": { + "notice": "This method can only by called by this `RelayHub`. It wraps the execution of the `RelayRequest` in a revertable frame context." + }, + "isRelayEscheatable(address)": { + "notice": "Uses `StakeManager` to check if the Relay Manager can be considered abandoned or not. Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise." + }, + "onRelayServerRegistered(address)": { + "notice": "The `RelayRegistrar` callback to notify the `RelayHub` that this `relayManager` has updated registration." + }, + "penalize(address,address)": { + "notice": "In case the Relay Worker has been found to be in violation of some rules by the `Penalizer` contract, the `Penalizer` will call this method to execute a penalization. The `RelayHub` will look up the Relay Manager of the given Relay Worker and will forward the call to the `StakeManager` contract. The `RelayHub` does not perform the actual penalization either." + }, + "relayCall(string,uint256,((address,address,uint256,uint256,uint256,bytes,uint256),(uint256,uint256,uint256,address,address,address,bytes,uint256)),bytes,bytes)": { + "notice": "Relays a transaction. For this to succeed, multiple conditions must be met: - `Paymaster`'s `preRelayCall` method must succeed and not revert. - the `msg.sender` must be a registered Relay Worker that the user signed to use. - the transaction's gas fees must be equal or larger than the ones that were signed by the sender. - the transaction must have enough gas to run all internal transactions if they use all gas available to them. - the `Paymaster` must have enough balance to pay the Relay Worker if all gas is spent.If all conditions are met, the call will be relayed and the `Paymaster` charged." + }, + "setConfiguration((uint256,uint256,uint256,uint256,uint256,address,uint8,uint80,uint16))": { + "notice": "Sets or changes the configuration of this `RelayHub`." + }, + "setMinimumStakes(address[],uint256[])": { + "notice": "Sets or changes the minimum amount of a given `token` that needs to be staked so that the Relay Manager is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking." + }, + "verifyRelayManagerStaked(address)": { + "notice": "Uses `StakeManager` to decide if the Relay Manager can be considered staked or not. Returns if the stake's token, amount and delay satisfy all requirements, reverts otherwise." + }, + "withdraw(address,uint256)": { + "notice": "Withdraws from an account's balance, sending it back to the caller. Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding. Emits a `Withdrawn` event." + }, + "withdrawMultiple(address[],uint256[])": { + "notice": "Withdraws from an account's balance, sending funds to multiple provided addresses. Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding. Emits a `Withdrawn` event for each destination." + } + }, + "notice": "This contract implements the `IRelayHub` interface for the EVM-compatible networks.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 8589, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 1178, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "config", + "offset": 0, + "slot": "1", + "type": "t_struct(RelayHubConfig)5166_storage" + }, + { + "astId": 1221, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "minimumStakePerToken", + "offset": 0, + "slot": "8", + "type": "t_mapping(t_contract(IERC20)9362,t_uint256)" + }, + { + "astId": 1284, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "workerToManager", + "offset": 0, + "slot": "9", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 1288, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "workerCount", + "offset": 0, + "slot": "10", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 1292, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "balances", + "offset": 0, + "slot": "11", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 1301, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "deprecationTime", + "offset": 0, + "slot": "12", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_contract(IERC20)9362": { + "encoding": "inplace", + "label": "contract IERC20", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_contract(IERC20)9362,t_uint256)": { + "encoding": "mapping", + "key": "t_contract(IERC20)9362", + "label": "mapping(contract IERC20 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(RelayHubConfig)5166_storage": { + "encoding": "inplace", + "label": "struct IRelayHub.RelayHubConfig", + "members": [ + { + "astId": 5149, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "maxWorkerCount", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 5151, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "gasReserve", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 5153, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "postOverhead", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 5155, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "gasOverhead", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 5157, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "minimumUnstakeDelay", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 5159, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "devAddress", + "offset": 0, + "slot": "5", + "type": "t_address" + }, + { + "astId": 5161, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "devFee", + "offset": 20, + "slot": "5", + "type": "t_uint8" + }, + { + "astId": 5163, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "baseRelayFee", + "offset": 21, + "slot": "5", + "type": "t_uint80" + }, + { + "astId": 5165, + "contract": "@opengsn/contracts/src/RelayHub.sol:RelayHub", + "label": "pctRelayFee", + "offset": 0, + "slot": "6", + "type": "t_uint16" + } + ], + "numberOfBytes": "224" + }, + "t_uint16": { + "encoding": "inplace", + "label": "uint16", + "numberOfBytes": "2" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + }, + "t_uint80": { + "encoding": "inplace", + "label": "uint80", + "numberOfBytes": "10" + } + } + } +} \ No newline at end of file diff --git a/gsn/deploy/data/deployments/amoy/RelayRegistrar.json b/gsn/deploy/data/deployments/amoy/RelayRegistrar.json new file mode 100644 index 00000000..7969c610 --- /dev/null +++ b/gsn/deploy/data/deployments/amoy/RelayRegistrar.json @@ -0,0 +1,634 @@ +{ + "address": "0x789A9BdA84A4aE86aCC8797971197729C3bfc42a", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_relayRegistrationMaxAge", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "relayHub", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32[3]", + "name": "relayUrl", + "type": "bytes32[3]" + } + ], + "name": "RelayServerRegistered", + "type": "event" + }, + { + "inputs": [], + "name": "getCreationBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayHub", + "type": "address" + }, + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "name": "getRelayInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "lastSeenBlockNumber", + "type": "uint32" + }, + { + "internalType": "uint40", + "name": "lastSeenTimestamp", + "type": "uint40" + }, + { + "internalType": "uint32", + "name": "firstSeenBlockNumber", + "type": "uint32" + }, + { + "internalType": "uint40", + "name": "firstSeenTimestamp", + "type": "uint40" + }, + { + "internalType": "bytes32[3]", + "name": "urlParts", + "type": "bytes32[3]" + }, + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "internalType": "struct IRelayRegistrar.RelayInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRelayRegistrationMaxAge", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayHub", + "type": "address" + } + ], + "name": "readRelayInfos", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "lastSeenBlockNumber", + "type": "uint32" + }, + { + "internalType": "uint40", + "name": "lastSeenTimestamp", + "type": "uint40" + }, + { + "internalType": "uint32", + "name": "firstSeenBlockNumber", + "type": "uint32" + }, + { + "internalType": "uint40", + "name": "firstSeenTimestamp", + "type": "uint40" + }, + { + "internalType": "bytes32[3]", + "name": "urlParts", + "type": "bytes32[3]" + }, + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "internalType": "struct IRelayRegistrar.RelayInfo[]", + "name": "info", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayHub", + "type": "address" + }, + { + "internalType": "uint256", + "name": "oldestBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "oldestBlockTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxCount", + "type": "uint256" + } + ], + "name": "readRelayInfosInRange", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "lastSeenBlockNumber", + "type": "uint32" + }, + { + "internalType": "uint40", + "name": "lastSeenTimestamp", + "type": "uint40" + }, + { + "internalType": "uint32", + "name": "firstSeenBlockNumber", + "type": "uint32" + }, + { + "internalType": "uint40", + "name": "firstSeenTimestamp", + "type": "uint40" + }, + { + "internalType": "bytes32[3]", + "name": "urlParts", + "type": "bytes32[3]" + }, + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "internalType": "struct IRelayRegistrar.RelayInfo[]", + "name": "info", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayHub", + "type": "address" + }, + { + "internalType": "bytes32[3]", + "name": "url", + "type": "bytes32[3]" + } + ], + "name": "registerRelayServer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_relayRegistrationMaxAge", + "type": "uint256" + } + ], + "name": "setRelayRegistrationMaxAge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x16313c7c49a963e70ccba4bcdfc415dbece6f9a24c2e78972c96531e7ac15228", + "receipt": { + "to": null, + "from": "0x61B1E290d2F465d6667336d4934941aa2517AfA2", + "contractAddress": "0x789A9BdA84A4aE86aCC8797971197729C3bfc42a", + "transactionIndex": 0, + "gasUsed": "755615", + "logsBloom": "0x00000000000000000008000000000000000000000000000000800000000000000000000000000002000000000000000000008000000000000000000000400000000000000000000000000000000000800001000000000000000100001000000000000000020000000000000000000800000000000000000080000000000000400000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000140000000004000000000000000008001000000000000000000000000000001100000000020000000000000000000000000000000008000000000000000000000000000100000", + "blockHash": "0x961288383b078eda7bb44c90968c5c2c25734d0273e16ed4d43dd2f74ff18040", + "transactionHash": "0x16313c7c49a963e70ccba4bcdfc415dbece6f9a24c2e78972c96531e7ac15228", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 4880208, + "transactionHash": "0x16313c7c49a963e70ccba4bcdfc415dbece6f9a24c2e78972c96531e7ac15228", + "address": "0x789A9BdA84A4aE86aCC8797971197729C3bfc42a", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000061b1e290d2f465d6667336d4934941aa2517afa2" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x961288383b078eda7bb44c90968c5c2c25734d0273e16ed4d43dd2f74ff18040" + }, + { + "transactionIndex": 0, + "blockNumber": 4880208, + "transactionHash": "0x16313c7c49a963e70ccba4bcdfc415dbece6f9a24c2e78972c96531e7ac15228", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x00000000000000000000000061b1e290d2f465d6667336d4934941aa2517afa2", + "0x0000000000000000000000004ad84f7014b7b44f723f284a85b1662337971439" + ], + "data": "0x00000000000000000000000000000000000000000000000000a111ab9b0ab5af000000000000000000000000000000000000000000000000023f17904476e80000000000000000000000000000000000000000000000000fb73b375bce50eaa5000000000000000000000000000000000000000000000000019e05e4a96c325100000000000000000000000000000000000000000000000fb7dc4907695ba054", + "logIndex": 1, + "blockHash": "0x961288383b078eda7bb44c90968c5c2c25734d0273e16ed4d43dd2f74ff18040" + } + ], + "blockNumber": 4880208, + "cumulativeGasUsed": "755615", + "status": 1, + "byzantium": true + }, + "args": [ + 15552000 + ], + "numDeployments": 1, + "solcInputHash": "766eaa539015b343a6f8732a84d5a9ae", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_relayRegistrationMaxAge\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayHub\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32[3]\",\"name\":\"relayUrl\",\"type\":\"bytes32[3]\"}],\"name\":\"RelayServerRegistered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"getCreationBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayHub\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"name\":\"getRelayInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"lastSeenBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"lastSeenTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"firstSeenBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"firstSeenTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"bytes32[3]\",\"name\":\"urlParts\",\"type\":\"bytes32[3]\"},{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"internalType\":\"struct IRelayRegistrar.RelayInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRelayRegistrationMaxAge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayHub\",\"type\":\"address\"}],\"name\":\"readRelayInfos\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"lastSeenBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"lastSeenTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"firstSeenBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"firstSeenTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"bytes32[3]\",\"name\":\"urlParts\",\"type\":\"bytes32[3]\"},{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"internalType\":\"struct IRelayRegistrar.RelayInfo[]\",\"name\":\"info\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayHub\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"oldestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"oldestBlockTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"readRelayInfosInRange\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"lastSeenBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"lastSeenTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"firstSeenBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint40\",\"name\":\"firstSeenTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"bytes32[3]\",\"name\":\"urlParts\",\"type\":\"bytes32[3]\"},{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"internalType\":\"struct IRelayRegistrar.RelayInfo[]\",\"name\":\"info\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayHub\",\"type\":\"address\"},{\"internalType\":\"bytes32[3]\",\"name\":\"url\",\"type\":\"bytes32[3]\"}],\"name\":\"registerRelayServer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_relayRegistrationMaxAge\",\"type\":\"uint256\"}],\"name\":\"setRelayRegistrationMaxAge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getCreationBlock()\":{\"returns\":{\"_0\":\"The block number in which the contract has been deployed.\"}},\"getRelayInfo(address,address)\":{\"params\":{\"relayHub\":\"The address of the `RelayHub` contract for which this action is performed.\",\"relayManager\":\"An address of a Relay Manager.\"},\"returns\":{\"_0\":\"All the details of the given Relay Manager's registration. Throws if relay not found for `RelayHub`.\"}},\"getRelayRegistrationMaxAge()\":{\"returns\":{\"_0\":\"The maximum age the relay is considered registered by default by this `RelayRegistrar`, in seconds.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"readRelayInfos(address)\":{\"params\":{\"relayHub\":\"The address of the `RelayHub` contract for which this action is performed.\"},\"returns\":{\"info\":\"The list of `RelayInfo`s of registered Relay Servers\"}},\"readRelayInfosInRange(address,uint256,uint256,uint256)\":{\"params\":{\"maxCount\":\"The maximum amount of relays to be returned by this function.\",\"oldestBlockNumber\":\"The latest block number in which a Relay Server may be registered.\",\"oldestBlockTimestamp\":\"The latest block timestamp in which a Relay Server may be registered.\",\"relayHub\":\"The address of the `RelayHub` contract for which this action is performed.\"},\"returns\":{\"info\":\"The list of `RelayInfo`s of registered Relay Servers\"}},\"registerRelayServer(address,bytes32[3])\":{\"params\":{\"relayHub\":\"The address of the `RelayHub` contract for which this action is performed.\",\"url\":\"The URL of the Relay Server that is listening to the clients' requests.\"}},\"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.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"The RelayRegistrar Implementation\",\"version\":1},\"userdoc\":{\"events\":{\"RelayServerRegistered(address,address,bytes32[3])\":{\"notice\":\"Emitted when a relay server registers or updates its details. Looking up these events allows a client to discover registered Relay Servers.\"}},\"kind\":\"user\",\"methods\":{\"readRelayInfos(address)\":{\"notice\":\"Read relay info of registered Relay Server from an on-chain storage.\"},\"readRelayInfosInRange(address,uint256,uint256,uint256)\":{\"notice\":\"Read relay info of registered Relay Server from an on-chain storage.\"},\"registerRelayServer(address,bytes32[3])\":{\"notice\":\"This function is called by Relay Servers in order to register or to update their registration.\"},\"setRelayRegistrationMaxAge(uint256)\":{\"notice\":\"Change the maximum relay registration age.\"}},\"notice\":\"Keeps a list of registered relayers.Provides view functions to read the list of registered relayers and filters out invalid ones.Protects the list from spamming entries: only staked relayers are added.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@opengsn/contracts/src/utils/RelayRegistrar.sol\":\"RelayRegistrar\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@opengsn/contracts/src/forwarder/IForwarder.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\n\\n/**\\n * @title The Forwarder Interface\\n * @notice The contracts implementing this interface take a role of authorization, authentication and replay protection\\n * for contracts that choose to trust a `Forwarder`, instead of relying on a mechanism built into the Ethereum protocol.\\n *\\n * @notice if the `Forwarder` contract decides that an incoming `ForwardRequest` is valid, it must append 20 bytes that\\n * represent the caller to the `data` field of the request and send this new data to the target address (the `to` field)\\n *\\n * :warning: **Warning** :warning: The Forwarder can have a full control over a `Recipient` contract.\\n * Any vulnerability in a `Forwarder` implementation can make all of its `Recipient` contracts susceptible!\\n * Recipient contracts should only trust forwarders that passed through security audit,\\n * otherwise they are susceptible to identity theft.\\n */\\ninterface IForwarder is IERC165 {\\n\\n /**\\n * @notice A representation of a request for a `Forwarder` to send `data` on behalf of a `from` to a target (`to`).\\n */\\n struct ForwardRequest {\\n address from;\\n address to;\\n uint256 value;\\n uint256 gas;\\n uint256 nonce;\\n bytes data;\\n uint256 validUntilTime;\\n }\\n\\n event DomainRegistered(bytes32 indexed domainSeparator, bytes domainValue);\\n\\n event RequestTypeRegistered(bytes32 indexed typeHash, string typeStr);\\n\\n /**\\n * @param from The address of a sender.\\n * @return The nonce for this address.\\n */\\n function getNonce(address from)\\n external view\\n returns(uint256);\\n\\n /**\\n * @notice Verify the transaction is valid and can be executed.\\n * Implementations must validate the signature and the nonce of the request are correct.\\n * Does not revert and returns successfully if the input is valid.\\n * Reverts if any validation has failed. For instance, if either signature or nonce are incorrect.\\n * Reverts if `domainSeparator` or `requestTypeHash` are not registered as well.\\n */\\n function verify(\\n ForwardRequest calldata forwardRequest,\\n bytes32 domainSeparator,\\n bytes32 requestTypeHash,\\n bytes calldata suffixData,\\n bytes calldata signature\\n ) external view;\\n\\n /**\\n * @notice Executes a transaction specified by the `ForwardRequest`.\\n * The transaction is first verified and then executed.\\n * The success flag and returned bytes array of the `CALL` are returned as-is.\\n *\\n * This method would revert only in case of a verification error.\\n *\\n * All the target errors are reported using the returned success flag and returned bytes array.\\n *\\n * @param forwardRequest All requested transaction parameters.\\n * @param domainSeparator The domain used when signing this request.\\n * @param requestTypeHash The request type used when signing this request.\\n * @param suffixData The ABI-encoded extension data for the current `RequestType` used when signing this request.\\n * @param signature The client signature to be validated.\\n *\\n * @return success The success flag of the underlying `CALL` to the target address.\\n * @return ret The byte array returned by the underlying `CALL` to the target address.\\n */\\n function execute(\\n ForwardRequest calldata forwardRequest,\\n bytes32 domainSeparator,\\n bytes32 requestTypeHash,\\n bytes calldata suffixData,\\n bytes calldata signature\\n )\\n external payable\\n returns (bool success, bytes memory ret);\\n\\n /**\\n * @notice Register a new Request typehash.\\n *\\n * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\\n *\\n * @param typeName The name of the request type.\\n * @param typeSuffix Any extra data after the generic params. Must contain add at least one param.\\n * The generic ForwardRequest type is always registered by the constructor.\\n */\\n function registerRequestType(string calldata typeName, string calldata typeSuffix) external;\\n\\n /**\\n * @notice Register a new domain separator.\\n *\\n * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\\n *\\n * @notice The domain separator must have the following fields: `name`, `version`, `chainId`, `verifyingContract`.\\n * The `chainId` is the current network's `chainId`, and the `verifyingContract` is this Forwarder's address.\\n * This method accepts the domain name and version to create and register the domain separator value.\\n * @param name The domain's display name.\\n * @param version The domain/protocol version.\\n */\\n function registerDomainSeparator(string calldata name, string calldata version) external;\\n}\\n\",\"keccak256\":\"0x28669953bd3dcc98a5f959fa3cac97444584b6fbe59341681b9a59f11a83b171\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/interfaces/IRelayHub.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\n\\nimport \\\"../utils/GsnTypes.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\n\\n/**\\n * @title The RelayHub interface\\n * @notice The implementation of this interface provides all the information the GSN client needs to\\n * create a valid `RelayRequest` and also serves as an entry point for such requests.\\n *\\n * @notice The RelayHub also handles all the related financial records and hold the balances of participants.\\n * The Paymasters keep their Ether deposited in the `RelayHub` in order to pay for the `RelayRequest`s that thay choose\\n * to pay for, and Relay Servers keep their earned Ether in the `RelayHub` until they choose to `withdraw()`\\n *\\n * @notice The RelayHub on each supported network only needs a single instance and there is usually no need for dApp\\n * developers or Relay Server operators to redeploy, reimplement, modify or override the `RelayHub`.\\n */\\ninterface IRelayHub is IERC165 {\\n /**\\n * @notice A struct that contains all the parameters of the `RelayHub` that can be modified after the deployment.\\n */\\n struct RelayHubConfig {\\n // maximum number of worker accounts allowed per manager\\n uint256 maxWorkerCount;\\n // Gas set aside for all relayCall() instructions to prevent unexpected out-of-gas exceptions\\n uint256 gasReserve;\\n // Gas overhead to calculate gasUseWithoutPost\\n uint256 postOverhead;\\n // Gas cost of all relayCall() instructions after actual 'calculateCharge()'\\n // Assume that relay has non-zero balance (costs 15'000 more otherwise).\\n uint256 gasOverhead;\\n // Minimum unstake delay seconds of a relay manager's stake on the StakeManager\\n uint256 minimumUnstakeDelay;\\n // Developers address\\n address devAddress;\\n // 0 < fee < 100, as percentage of total charge from paymaster to relayer\\n uint8 devFee;\\n // baseRelayFee The base fee the Relay Server charges for a single transaction in Ether, in wei.\\n uint80 baseRelayFee;\\n // pctRelayFee The percent of the total charge to add as a Relay Server fee to the total charge.\\n uint16 pctRelayFee;\\n }\\n\\n /// @notice Emitted when a configuration of the `RelayHub` is changed\\n event RelayHubConfigured(RelayHubConfig config);\\n\\n /// @notice Emitted when relays are added by a relayManager\\n event RelayWorkersAdded(\\n address indexed relayManager,\\n address[] newRelayWorkers,\\n uint256 workersCount\\n );\\n\\n /// @notice Emitted when an account withdraws funds from the `RelayHub`.\\n event Withdrawn(\\n address indexed account,\\n address indexed dest,\\n uint256 amount\\n );\\n\\n /// @notice Emitted when `depositFor` is called, including the amount and account that was funded.\\n event Deposited(\\n address indexed paymaster,\\n address indexed from,\\n uint256 amount\\n );\\n\\n /// @notice Emitted for each token configured for staking in setMinimumStakes\\n event StakingTokenDataChanged(\\n address token,\\n uint256 minimumStake\\n );\\n\\n /**\\n * @notice Emitted when an attempt to relay a call fails and the `Paymaster` does not accept the transaction.\\n * The actual relayed call was not executed, and the recipient not charged.\\n * @param reason contains a revert reason returned from preRelayedCall or forwarder.\\n */\\n event TransactionRejectedByPaymaster(\\n address indexed relayManager,\\n address indexed paymaster,\\n bytes32 indexed relayRequestID,\\n address from,\\n address to,\\n address relayWorker,\\n bytes4 selector,\\n uint256 innerGasUsed,\\n bytes reason\\n );\\n\\n /**\\n * @notice Emitted when a transaction is relayed. Note that the actual internal function call might be reverted.\\n * The reason for a revert will be indicated in the `status` field of a corresponding `RelayCallStatus` value.\\n * @notice `charge` is the Ether value deducted from the `Paymaster` balance.\\n * The amount added to the `relayManager` balance will be lower if there is an activated `devFee` in the `config`.\\n */\\n event TransactionRelayed(\\n address indexed relayManager,\\n address indexed relayWorker,\\n bytes32 indexed relayRequestID,\\n address from,\\n address to,\\n address paymaster,\\n bytes4 selector,\\n RelayCallStatus status,\\n uint256 charge\\n );\\n\\n /// @notice This event is emitted in case the internal function returns a value or reverts with a revert string.\\n event TransactionResult(\\n RelayCallStatus status,\\n bytes returnValue\\n );\\n\\n /// @notice This event is emitted in case this `RelayHub` is deprecated and will stop serving transactions soon.\\n event HubDeprecated(uint256 deprecationTime);\\n\\n /**\\n * @notice This event is emitted in case a `relayManager` has been deemed \\\"abandoned\\\" for being\\n * unresponsive for a prolonged period of time.\\n * @notice This event means the entire balance of the relay has been transferred to the `devAddress`.\\n */\\n event AbandonedRelayManagerBalanceEscheated(\\n address indexed relayManager,\\n uint256 balance\\n );\\n\\n /**\\n * Error codes that describe all possible failure reasons reported in the `TransactionRelayed` event `status` field.\\n * @param OK The transaction was successfully relayed and execution successful - never included in the event.\\n * @param RelayedCallFailed The transaction was relayed, but the relayed call failed.\\n * @param RejectedByPreRelayed The transaction was not relayed due to preRelatedCall reverting.\\n * @param RejectedByForwarder The transaction was not relayed due to forwarder check (signature,nonce).\\n * @param PostRelayedFailed The transaction was relayed and reverted due to postRelatedCall reverting.\\n * @param PaymasterBalanceChanged The transaction was relayed and reverted due to the paymaster balance change.\\n */\\n enum RelayCallStatus {\\n OK,\\n RelayedCallFailed,\\n RejectedByPreRelayed,\\n RejectedByForwarder,\\n RejectedByRecipientRevert,\\n PostRelayedFailed,\\n PaymasterBalanceChanged\\n }\\n\\n /**\\n * @notice Add new worker addresses controlled by the sender who must be a staked Relay Manager address.\\n * Emits a `RelayWorkersAdded` event.\\n * This function can be called multiple times, emitting new events.\\n */\\n function addRelayWorkers(address[] calldata newRelayWorkers) external;\\n\\n /**\\n * @notice The `RelayRegistrar` callback to notify the `RelayHub` that this `relayManager` has updated registration.\\n */\\n function onRelayServerRegistered(address relayManager) external;\\n\\n // Balance management\\n\\n /**\\n * @notice Deposits ether for a `Paymaster`, so that it can and pay for relayed transactions.\\n * :warning: **Warning** :warning: Unused balance can only be withdrawn by the holder itself, by calling `withdraw`.\\n * Emits a `Deposited` event.\\n */\\n function depositFor(address target) external payable;\\n\\n /**\\n * @notice Withdraws from an account's balance, sending it back to the caller.\\n * Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding.\\n * Emits a `Withdrawn` event.\\n */\\n function withdraw(address payable dest, uint256 amount) external;\\n\\n /**\\n * @notice Withdraws from an account's balance, sending funds to multiple provided addresses.\\n * Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding.\\n * Emits a `Withdrawn` event for each destination.\\n */\\n function withdrawMultiple(address payable[] memory dest, uint256[] memory amount) external;\\n\\n // Relaying\\n\\n\\n /**\\n * @notice Relays a transaction. For this to succeed, multiple conditions must be met:\\n * - `Paymaster`'s `preRelayCall` method must succeed and not revert.\\n * - the `msg.sender` must be a registered Relay Worker that the user signed to use.\\n * - the transaction's gas fees must be equal or larger than the ones that were signed by the sender.\\n * - the transaction must have enough gas to run all internal transactions if they use all gas available to them.\\n * - the `Paymaster` must have enough balance to pay the Relay Worker if all gas is spent.\\n *\\n * @notice If all conditions are met, the call will be relayed and the `Paymaster` charged.\\n *\\n * @param domainSeparatorName The name of the Domain Separator used to verify the EIP-712 signature\\n * @param maxAcceptanceBudget The maximum valid value for `paymaster.getGasLimits().acceptanceBudget` to return.\\n * @param relayRequest All details of the requested relayed call.\\n * @param signature The client's EIP-712 signature over the `relayRequest` struct.\\n * @param approvalData The dapp-specific data forwarded to the `Paymaster`'s `preRelayedCall` method.\\n * This value is **not** verified by the `RelayHub` in any way.\\n * As an example, it can be used to pass some kind of a third-party signature to the `Paymaster` for verification.\\n *\\n * Emits a `TransactionRelayed` event regardless of whether the transaction succeeded or failed.\\n */\\n function relayCall(\\n string calldata domainSeparatorName,\\n uint256 maxAcceptanceBudget,\\n GsnTypes.RelayRequest calldata relayRequest,\\n bytes calldata signature,\\n bytes calldata approvalData\\n )\\n external\\n returns (\\n bool paymasterAccepted,\\n uint256 charge,\\n IRelayHub.RelayCallStatus status,\\n bytes memory returnValue\\n );\\n\\n /**\\n * @notice In case the Relay Worker has been found to be in violation of some rules by the `Penalizer` contract,\\n * the `Penalizer` will call this method to execute a penalization.\\n * The `RelayHub` will look up the Relay Manager of the given Relay Worker and will forward the call to\\n * the `StakeManager` contract. The `RelayHub` does not perform the actual penalization either.\\n * @param relayWorker The address of the Relay Worker that committed a penalizable offense.\\n * @param beneficiary The address that called the `Penalizer` and will receive a reward for it.\\n */\\n function penalize(address relayWorker, address payable beneficiary) external;\\n\\n /**\\n * @notice Sets or changes the configuration of this `RelayHub`.\\n * @param _config The new configuration.\\n */\\n function setConfiguration(RelayHubConfig memory _config) external;\\n\\n /**\\n * @notice Sets or changes the minimum amount of a given `token` that needs to be staked so that the Relay Manager\\n * is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.\\n * @param token An array of addresses of ERC-20 compatible tokens.\\n * @param minimumStake An array of minimal amounts necessary for a corresponding token, in wei.\\n */\\n function setMinimumStakes(IERC20[] memory token, uint256[] memory minimumStake) external;\\n\\n /**\\n * @notice Deprecate hub by reverting all incoming `relayCall()` calls starting from a given timestamp\\n * @param _deprecationTime The timestamp in seconds after which the `RelayHub` stops serving transactions.\\n */\\n function deprecateHub(uint256 _deprecationTime) external;\\n\\n /**\\n * @notice\\n * @param relayManager\\n */\\n function escheatAbandonedRelayBalance(address relayManager) external;\\n\\n /**\\n * @notice The fee is expressed as a base fee in wei plus percentage of the actual charge.\\n * For example, a value '40' stands for a 40% fee, so the recipient will be charged for 1.4 times the spent amount.\\n * @param gasUsed An amount of gas used by the transaction.\\n * @param relayData The details of a transaction signed by the sender.\\n * @return The calculated charge, in wei.\\n */\\n function calculateCharge(uint256 gasUsed, GsnTypes.RelayData calldata relayData) external view returns (uint256);\\n\\n /**\\n * @notice The fee is expressed as a percentage of the actual charge.\\n * For example, a value '40' stands for a 40% fee, so the Relay Manager will only get 60% of the `charge`.\\n * @param charge The amount of Ether in wei the Paymaster will be charged for this transaction.\\n * @return The calculated devFee, in wei.\\n */\\n function calculateDevCharge(uint256 charge) external view returns (uint256);\\n /* getters */\\n\\n /// @return config The configuration of the `RelayHub`.\\n function getConfiguration() external view returns (RelayHubConfig memory config);\\n\\n /**\\n * @param token An address of an ERC-20 compatible tokens.\\n * @return The minimum amount of a given `token` that needs to be staked so that the Relay Manager\\n * is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.\\n */\\n function getMinimumStakePerToken(IERC20 token) external view returns (uint256);\\n\\n /**\\n * @param worker An address of the Relay Worker.\\n * @return The address of its Relay Manager.\\n */\\n function getWorkerManager(address worker) external view returns (address);\\n\\n /**\\n * @param manager An address of the Relay Manager.\\n * @return The count of Relay Workers associated with this Relay Manager.\\n */\\n function getWorkerCount(address manager) external view returns (uint256);\\n\\n /// @return An account's balance. It can be either a deposit of a `Paymaster`, or a revenue of a Relay Manager.\\n function balanceOf(address target) external view returns (uint256);\\n\\n /// @return The `StakeManager` address for this `RelayHub`.\\n function getStakeManager() external view returns (IStakeManager);\\n\\n /// @return The `Penalizer` address for this `RelayHub`.\\n function getPenalizer() external view returns (address);\\n\\n /// @return The `RelayRegistrar` address for this `RelayHub`.\\n function getRelayRegistrar() external view returns (address);\\n\\n /// @return The `BatchGateway` address for this `RelayHub`.\\n function getBatchGateway() external view returns (address);\\n\\n /**\\n * @notice Uses `StakeManager` to decide if the Relay Manager can be considered staked or not.\\n * Returns if the stake's token, amount and delay satisfy all requirements, reverts otherwise.\\n */\\n function verifyRelayManagerStaked(address relayManager) external view;\\n\\n /**\\n * @notice Uses `StakeManager` to check if the Relay Manager can be considered abandoned or not.\\n * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\\n */\\n function isRelayEscheatable(address relayManager) external view returns (bool);\\n\\n /// @return `true` if the `RelayHub` is deprecated, `false` it it is not deprecated and can serve transactions.\\n function isDeprecated() external view returns (bool);\\n\\n /// @return The timestamp from which the hub no longer allows relaying calls.\\n function getDeprecationTime() external view returns (uint256);\\n\\n /// @return The block number in which the contract has been deployed.\\n function getCreationBlock() external view returns (uint256);\\n\\n /// @return a SemVer-compliant version of the `RelayHub` contract.\\n function versionHub() external view returns (string memory);\\n\\n /// @return A total measurable amount of gas left to current execution. Same as 'gasleft()' for pure EVMs.\\n function aggregateGasleft() external view returns (uint256);\\n}\\n\\n\",\"keccak256\":\"0x0ab29ca5985c98f530e5985e3d9dd14f00d34527410ce980b51b26e57bb0121c\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/interfaces/IRelayRegistrar.sol\":{\"content\":\"//SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.6;\\n\\nimport \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\n\\n/**\\n * @title The RelayRegistrar Interface\\n * @notice The on-chain registrar for all registered Relay Managers.\\n *\\n * @notice The client can use an implementation of a `RelayRegistrar` to find relay registration info.\\n *\\n */\\ninterface IRelayRegistrar is IERC165 {\\n\\n /**\\n * @notice A struct containing all the information necessary to client to interact with the Relay Server.\\n */\\n struct RelayInfo {\\n //last registration block number\\n uint32 lastSeenBlockNumber;\\n //last registration block timestamp\\n uint40 lastSeenTimestamp;\\n //stake (first registration) block number\\n uint32 firstSeenBlockNumber;\\n //stake (first registration) block timestamp\\n uint40 firstSeenTimestamp;\\n bytes32[3] urlParts;\\n address relayManager;\\n }\\n\\n /**\\n * @notice Emitted when a relay server registers or updates its details.\\n * Looking up these events allows a client to discover registered Relay Servers.\\n */\\n event RelayServerRegistered(\\n address indexed relayManager,\\n address indexed relayHub,\\n bytes32[3] relayUrl\\n );\\n\\n /**\\n * @notice This function is called by Relay Servers in order to register or to update their registration.\\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\\n * @param url The URL of the Relay Server that is listening to the clients' requests.\\n */\\n function registerRelayServer(\\n address relayHub,\\n bytes32[3] calldata url\\n ) external;\\n\\n /**\\n * @return The block number in which the contract has been deployed.\\n */\\n function getCreationBlock() external view returns (uint256);\\n\\n /**\\n * @return The maximum age the relay is considered registered by default by this `RelayRegistrar`, in seconds.\\n */\\n function getRelayRegistrationMaxAge() external view returns (uint256);\\n\\n /**\\n * @notice Change the maximum relay registration age.\\n */\\n function setRelayRegistrationMaxAge(uint256) external;\\n\\n /**\\n * @param relayManager An address of a Relay Manager.\\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\\n * @return info All the details of the given Relay Manager's registration. Throws if relay not found for `RelayHub`.\\n */\\n function getRelayInfo(address relayHub, address relayManager) external view returns (RelayInfo memory info);\\n\\n /**\\n * @notice Read relay info of registered Relay Server from an on-chain storage.\\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\\n * @return info The list of `RelayInfo`s of registered Relay Servers\\n */\\n function readRelayInfos(\\n address relayHub\\n ) external view returns (\\n RelayInfo[] memory info\\n );\\n\\n /**\\n * @notice Read relay info of registered Relay Server from an on-chain storage.\\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\\n * @param maxCount The maximum amount of relays to be returned by this function.\\n * @param oldestBlockNumber The latest block number in which a Relay Server may be registered.\\n * @param oldestBlockTimestamp The latest block timestamp in which a Relay Server may be registered.\\n * @return info The list of `RelayInfo`s of registered Relay Servers\\n */\\n function readRelayInfosInRange(\\n address relayHub,\\n uint256 oldestBlockNumber,\\n uint256 oldestBlockTimestamp,\\n uint256 maxCount\\n ) external view returns (\\n RelayInfo[] memory info\\n );\\n}\\n\",\"keccak256\":\"0x9f4ac5bead0cc949f8e1b89f1666527286b282e86e57b59de533b3f650927cfd\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @title The StakeManager Interface\\n * @notice In order to prevent an attacker from registering a large number of unresponsive relays, the GSN requires\\n * the Relay Server to maintain a permanently locked stake in the system before being able to register.\\n *\\n * @notice Also, in some cases the behavior of a Relay Server may be found to be illegal by a `Penalizer` contract.\\n * In such case, the stake will never be returned to the Relay Server operator and will be slashed.\\n *\\n * @notice An implementation of this interface is tasked with keeping Relay Servers' stakes, made in any ERC-20 token.\\n * Note that the `RelayHub` chooses which ERC-20 tokens to support and how much stake is needed.\\n */\\ninterface IStakeManager is IERC165 {\\n\\n /// @notice Emitted when a `stake` or `unstakeDelay` are initialized or increased.\\n event StakeAdded(\\n address indexed relayManager,\\n address indexed owner,\\n IERC20 token,\\n uint256 stake,\\n uint256 unstakeDelay\\n );\\n\\n /// @notice Emitted once a stake is scheduled for withdrawal.\\n event StakeUnlocked(\\n address indexed relayManager,\\n address indexed owner,\\n uint256 withdrawTime\\n );\\n\\n /// @notice Emitted when owner withdraws `relayManager` funds.\\n event StakeWithdrawn(\\n address indexed relayManager,\\n address indexed owner,\\n IERC20 token,\\n uint256 amount\\n );\\n\\n /// @notice Emitted when an authorized `RelayHub` penalizes a `relayManager`.\\n event StakePenalized(\\n address indexed relayManager,\\n address indexed beneficiary,\\n IERC20 token,\\n uint256 reward\\n );\\n\\n /// @notice Emitted when a `relayManager` adds a new `RelayHub` to a list of authorized.\\n event HubAuthorized(\\n address indexed relayManager,\\n address indexed relayHub\\n );\\n\\n /// @notice Emitted when a `relayManager` removes a `RelayHub` from a list of authorized.\\n event HubUnauthorized(\\n address indexed relayManager,\\n address indexed relayHub,\\n uint256 removalTime\\n );\\n\\n /// @notice Emitted when a `relayManager` sets its `owner`. This is necessary to prevent stake hijacking.\\n event OwnerSet(\\n address indexed relayManager,\\n address indexed owner\\n );\\n\\n /// @notice Emitted when a `burnAddress` is changed.\\n event BurnAddressSet(\\n address indexed burnAddress\\n );\\n\\n /// @notice Emitted when a `devAddress` is changed.\\n event DevAddressSet(\\n address indexed devAddress\\n );\\n\\n /// @notice Emitted if Relay Server is inactive for an `abandonmentDelay` and contract owner initiates its removal.\\n event RelayServerAbandoned(\\n address indexed relayManager,\\n uint256 abandonedTime\\n );\\n\\n /// @notice Emitted to indicate an action performed by a relay server to prevent it from being marked as abandoned.\\n event RelayServerKeepalive(\\n address indexed relayManager,\\n uint256 keepaliveTime\\n );\\n\\n /// @notice Emitted when the stake of an abandoned relayer has been confiscated and transferred to the `devAddress`.\\n event AbandonedRelayManagerStakeEscheated(\\n address indexed relayManager,\\n address indexed owner,\\n IERC20 token,\\n uint256 amount\\n );\\n\\n /**\\n * @param stake - amount of ether staked for this relay\\n * @param unstakeDelay - number of seconds to elapse before the owner can retrieve the stake after calling 'unlock'\\n * @param withdrawTime - timestamp in seconds when 'withdraw' will be callable, or zero if the unlock has not been called\\n * @param owner - address that receives revenue and manages relayManager's stake\\n */\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelay;\\n uint256 withdrawTime;\\n uint256 abandonedTime;\\n uint256 keepaliveTime;\\n IERC20 token;\\n address owner;\\n }\\n\\n struct RelayHubInfo {\\n uint256 removalTime;\\n }\\n\\n /**\\n * @param devAddress - the address that will receive the 'abandoned' stake\\n * @param abandonmentDelay - the amount of time after which the relay can be marked as 'abandoned'\\n * @param escheatmentDelay - the amount of time after which the abandoned relay's stake and balance may be withdrawn to the `devAddress`\\n */\\n struct AbandonedRelayServerConfig {\\n address devAddress;\\n uint256 abandonmentDelay;\\n uint256 escheatmentDelay;\\n }\\n\\n /**\\n * @notice Set the owner of a Relay Manager. Called only by the RelayManager itself.\\n * Note that owners cannot transfer ownership - if the entry already exists, reverts.\\n * @param owner - owner of the relay (as configured off-chain)\\n */\\n function setRelayManagerOwner(address owner) external;\\n\\n /**\\n * @notice Put a stake for a relayManager and set its unstake delay.\\n * Only the owner can call this function. If the entry does not exist, reverts.\\n * The owner must give allowance of the ERC-20 token to the StakeManager before calling this method.\\n * It is the RelayHub who has a configurable list of minimum stakes per token. StakeManager accepts all tokens.\\n * @param token The address of an ERC-20 token that is used by the relayManager as a stake\\n * @param relayManager The address that represents a stake entry and controls relay registrations on relay hubs\\n * @param unstakeDelay The number of seconds to elapse before an owner can retrieve the stake after calling `unlock`\\n * @param amount The amount of tokens to be taken from the relayOwner and locked in the StakeManager as a stake\\n */\\n function stakeForRelayManager(IERC20 token, address relayManager, uint256 unstakeDelay, uint256 amount) external;\\n\\n /**\\n * @notice Schedule the unlocking of the stake. The `unstakeDelay` must pass before owner can call `withdrawStake`.\\n * @param relayManager The address of a Relay Manager whose stake is to be unlocked.\\n */\\n function unlockStake(address relayManager) external;\\n /**\\n * @notice Withdraw the unlocked stake.\\n * @param relayManager The address of a Relay Manager whose stake is to be withdrawn.\\n */\\n function withdrawStake(address relayManager) external;\\n\\n /**\\n * @notice Add the `RelayHub` to a list of authorized by this Relay Manager.\\n * This allows the RelayHub to penalize this Relay Manager. The `RelayHub` cannot trust a Relay it cannot penalize.\\n * @param relayManager The address of a Relay Manager whose stake is to be authorized for the new `RelayHub`.\\n * @param relayHub The address of a `RelayHub` to be authorized.\\n */\\n function authorizeHubByOwner(address relayManager, address relayHub) external;\\n\\n /**\\n * @notice Same as `authorizeHubByOwner` but can be called by the RelayManager itself.\\n */\\n function authorizeHubByManager(address relayHub) external;\\n\\n /**\\n * @notice Remove the `RelayHub` from a list of authorized by this Relay Manager.\\n * @param relayManager The address of a Relay Manager.\\n * @param relayHub The address of a `RelayHub` to be unauthorized.\\n */\\n function unauthorizeHubByOwner(address relayManager, address relayHub) external;\\n\\n /**\\n * @notice Same as `unauthorizeHubByOwner` but can be called by the RelayManager itself.\\n */\\n function unauthorizeHubByManager(address relayHub) external;\\n\\n /**\\n * Slash the stake of the relay relayManager. In order to prevent stake kidnapping, burns part of stake on the way.\\n * @param relayManager The address of a Relay Manager to be penalized.\\n * @param beneficiary The address that receives part of the penalty amount.\\n * @param amount A total amount of penalty to be withdrawn from stake.\\n */\\n function penalizeRelayManager(address relayManager, address beneficiary, uint256 amount) external;\\n\\n /**\\n * @notice Allows the contract owner to set the given `relayManager` as abandoned after a configurable delay.\\n * Its entire stake and balance will be taken from a relay if it does not respond to being marked as abandoned.\\n */\\n function markRelayAbandoned(address relayManager) external;\\n\\n /**\\n * @notice If more than `abandonmentDelay` has passed since the last Keepalive transaction, and relay manager\\n * has been marked as abandoned, and after that more that `escheatmentDelay` have passed, entire stake and\\n * balance will be taken from this relay.\\n */\\n function escheatAbandonedRelayStake(address relayManager) external;\\n\\n /**\\n * @notice Sets a new `keepaliveTime` for the given `relayManager`, preventing it from being marked as abandoned.\\n * Can be called by an authorized `RelayHub` or by the `relayOwner` address.\\n */\\n function updateRelayKeepaliveTime(address relayManager) external;\\n\\n /**\\n * @notice Check if the Relay Manager can be considered abandoned or not.\\n * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\\n */\\n function isRelayEscheatable(address relayManager) external view returns(bool);\\n\\n /**\\n * @notice Get the stake details information for the given Relay Manager.\\n * @param relayManager The address of a Relay Manager.\\n * @return stakeInfo The `StakeInfo` structure.\\n * @return isSenderAuthorizedHub `true` if the `msg.sender` for this call was a `RelayHub` that is authorized now.\\n * `false` if the `msg.sender` for this call is not authorized.\\n */\\n function getStakeInfo(address relayManager) external view returns (StakeInfo memory stakeInfo, bool isSenderAuthorizedHub);\\n\\n /**\\n * @return The maximum unstake delay this `StakeManger` allows. This is to prevent locking money forever by mistake.\\n */\\n function getMaxUnstakeDelay() external view returns (uint256);\\n\\n /**\\n * @notice Change the address that will receive the 'burned' part of the penalized stake.\\n * This is done to prevent malicious Relay Server from penalizing itself and breaking even.\\n */\\n function setBurnAddress(address _burnAddress) external;\\n\\n /**\\n * @return The address that will receive the 'burned' part of the penalized stake.\\n */\\n function getBurnAddress() external view returns (address);\\n\\n /**\\n * @notice Change the address that will receive the 'abandoned' stake.\\n * This is done to prevent Relay Servers that lost their keys from losing access to funds.\\n */\\n function setDevAddress(address _burnAddress) external;\\n\\n /**\\n * @return The structure that contains all configuration values for the 'abandoned' stake.\\n */\\n function getAbandonedRelayServerConfig() external view returns (AbandonedRelayServerConfig memory);\\n\\n /**\\n * @return the block number in which the contract has been deployed.\\n */\\n function getCreationBlock() external view returns (uint256);\\n\\n /**\\n * @return a SemVer-compliant version of the `StakeManager` contract.\\n */\\n function versionSM() external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x77035b55ca4c09cb499bc0cab3f9e791d77597b148dbfee8bf94ca6c0039c3e0\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/utils/GsnTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.0;\\n\\nimport \\\"../forwarder/IForwarder.sol\\\";\\n\\ninterface GsnTypes {\\n /// @notice maxFeePerGas, maxPriorityFeePerGas, pctRelayFee and baseRelayFee must be validated inside of the paymaster's preRelayedCall in order not to overpay\\n struct RelayData {\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n uint256 transactionCalldataGasUsed;\\n address relayWorker;\\n address paymaster;\\n address forwarder;\\n bytes paymasterData;\\n uint256 clientId;\\n }\\n\\n //note: must start with the ForwardRequest to be an extension of the generic forwarder\\n struct RelayRequest {\\n IForwarder.ForwardRequest request;\\n RelayData relayData;\\n }\\n}\\n\",\"keccak256\":\"0x9fb51c540f32939f1ee291e3fa709be64f7c73485bd7b87c6624c3567dd42a1b\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/utils/MinLibBytes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// minimal bytes manipulation required by GSN\\n// a minimal subset from 0x/LibBytes\\n/* solhint-disable no-inline-assembly */\\npragma solidity ^0.8.0;\\n\\nlibrary MinLibBytes {\\n\\n //truncate the given parameter (in-place) if its length is above the given maximum length\\n // do nothing otherwise.\\n //NOTE: solidity warns unless the method is marked \\\"pure\\\", but it DOES modify its parameter.\\n function truncateInPlace(bytes memory data, uint256 maxlen) internal pure {\\n if (data.length > maxlen) {\\n assembly { mstore(data, maxlen) }\\n }\\n }\\n\\n /// @dev Reads an address from a position in a byte array.\\n /// @param b Byte array containing an address.\\n /// @param index Index in byte array of address.\\n /// @return result address from byte array.\\n function readAddress(\\n bytes memory b,\\n uint256 index\\n )\\n internal\\n pure\\n returns (address result)\\n {\\n require (b.length >= index + 20, \\\"readAddress: data too short\\\");\\n\\n // Add offset to index:\\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\\n index += 20;\\n\\n // Read address from array memory\\n assembly {\\n // 1. Add index to address of bytes array\\n // 2. Load 32-byte word from memory\\n // 3. Apply 20-byte mask to obtain address\\n result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)\\n }\\n return result;\\n }\\n\\n function readBytes32(\\n bytes memory b,\\n uint256 index\\n )\\n internal\\n pure\\n returns (bytes32 result)\\n {\\n require(b.length >= index + 32, \\\"readBytes32: data too short\\\" );\\n\\n // Read the bytes32 from array memory\\n assembly {\\n result := mload(add(b, add(index,32)))\\n }\\n return result;\\n }\\n\\n /// @dev Reads a uint256 value from a position in a byte array.\\n /// @param b Byte array containing a uint256 value.\\n /// @param index Index in byte array of uint256 value.\\n /// @return result uint256 value from byte array.\\n function readUint256(\\n bytes memory b,\\n uint256 index\\n )\\n internal\\n pure\\n returns (uint256 result)\\n {\\n result = uint256(readBytes32(b, index));\\n return result;\\n }\\n\\n function readBytes4(\\n bytes memory b,\\n uint256 index\\n )\\n internal\\n pure\\n returns (bytes4 result)\\n {\\n require(b.length >= index + 4, \\\"readBytes4: data too short\\\");\\n\\n // Read the bytes4 from array memory\\n assembly {\\n result := mload(add(b, add(index,32)))\\n // Solidity does not require us to clean the trailing bytes.\\n // We do it anyway\\n result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)\\n }\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x8063af8e0f134be3d794ad39bdc0041f33a16c91a4ee7abb968d4c15c8d10c54\",\"license\":\"MIT\"},\"@opengsn/contracts/src/utils/RelayRegistrar.sol\":{\"content\":\"// solhint-disable not-rely-on-time\\n//SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.6;\\n/* solhint-disable no-inline-assembly */\\n\\n// #if ENABLE_CONSOLE_LOG\\nimport \\\"hardhat/console.sol\\\";\\n// #endif\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport \\\"./MinLibBytes.sol\\\";\\nimport \\\"../interfaces/IRelayHub.sol\\\";\\nimport \\\"../interfaces/IRelayRegistrar.sol\\\";\\n\\n/**\\n * @title The RelayRegistrar Implementation\\n * @notice Keeps a list of registered relayers.\\n *\\n * @notice Provides view functions to read the list of registered relayers and filters out invalid ones.\\n *\\n * @notice Protects the list from spamming entries: only staked relayers are added.\\n */\\ncontract RelayRegistrar is IRelayRegistrar, Ownable, ERC165 {\\n using MinLibBytes for bytes;\\n\\n uint256 private constant MAX_RELAYS_RETURNED_COUNT = 1000;\\n\\n /// @notice Mapping from `RelayHub` address to a mapping from a Relay Manager address to its registration details.\\n mapping(address => mapping(address => RelayInfo)) internal values;\\n\\n /// @notice Mapping from `RelayHub` address to an array of Relay Managers that are registered on that `RelayHub`.\\n mapping(address => address[]) internal indexedValues;\\n\\n uint256 private immutable creationBlock;\\n\\n uint256 private relayRegistrationMaxAge;\\n\\n constructor(uint256 _relayRegistrationMaxAge) {\\n setRelayRegistrationMaxAge(_relayRegistrationMaxAge);\\n creationBlock = block.number;\\n }\\n\\n /// @inheritdoc IRelayRegistrar\\n function getCreationBlock() external override view returns (uint256){\\n return creationBlock;\\n }\\n\\n /// @inheritdoc IRelayRegistrar\\n function getRelayRegistrationMaxAge() external override view returns (uint256){\\n return relayRegistrationMaxAge;\\n }\\n\\n /// @inheritdoc IRelayRegistrar\\n function setRelayRegistrationMaxAge(uint256 _relayRegistrationMaxAge) public override onlyOwner {\\n relayRegistrationMaxAge = _relayRegistrationMaxAge;\\n }\\n\\n /// @inheritdoc IERC165\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\\n return interfaceId == type(IRelayRegistrar).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /// @inheritdoc IRelayRegistrar\\n function registerRelayServer(\\n address relayHub,\\n bytes32[3] calldata url\\n ) external override {\\n address relayManager = msg.sender;\\n IRelayHub(relayHub).onRelayServerRegistered(relayManager);\\n emit RelayServerRegistered(relayManager, relayHub, url);\\n storeRelayServerRegistration(relayManager, relayHub, url);\\n }\\n\\n function addItem(address relayHub, address relayManager) internal returns (RelayInfo storage) {\\n RelayInfo storage storageInfo = values[relayHub][relayManager];\\n if (storageInfo.lastSeenBlockNumber == 0) {\\n indexedValues[relayHub].push(relayManager);\\n }\\n return storageInfo;\\n }\\n\\n function storeRelayServerRegistration(\\n address relayManager,\\n address relayHub,\\n bytes32[3] calldata url\\n ) internal {\\n RelayInfo storage storageInfo = addItem(relayHub, relayManager);\\n if (storageInfo.firstSeenBlockNumber == 0) {\\n storageInfo.firstSeenBlockNumber = uint32(block.number);\\n storageInfo.firstSeenTimestamp = uint40(block.timestamp);\\n }\\n storageInfo.lastSeenBlockNumber = uint32(block.number);\\n storageInfo.lastSeenTimestamp = uint40(block.timestamp);\\n storageInfo.relayManager = relayManager;\\n storageInfo.urlParts = url;\\n }\\n\\n /// @inheritdoc IRelayRegistrar\\n function getRelayInfo(address relayHub, address relayManager) public view override returns (RelayInfo memory) {\\n RelayInfo memory info = values[relayHub][relayManager];\\n require(info.lastSeenBlockNumber != 0, \\\"relayManager not found\\\");\\n return info;\\n }\\n\\n /// @inheritdoc IRelayRegistrar\\n function readRelayInfos(\\n address relayHub\\n )\\n public\\n view\\n override\\n returns (\\n RelayInfo[] memory info\\n ) {\\n uint256 blockTimestamp = block.timestamp;\\n uint256 oldestBlockTimestamp = blockTimestamp >= relayRegistrationMaxAge ? blockTimestamp - relayRegistrationMaxAge : 0;\\n return readRelayInfosInRange(relayHub, 0, oldestBlockTimestamp, MAX_RELAYS_RETURNED_COUNT);\\n }\\n\\n /// @inheritdoc IRelayRegistrar\\n function readRelayInfosInRange(\\n address relayHub,\\n uint256 oldestBlockNumber,\\n uint256 oldestBlockTimestamp,\\n uint256 maxCount\\n )\\n public\\n view\\n override\\n returns (\\n RelayInfo[] memory info\\n ) {\\n address[] storage items = indexedValues[relayHub];\\n uint256 filled = 0;\\n info = new RelayInfo[](items.length < maxCount ? items.length : maxCount);\\n for (uint256 i = 0; i < items.length; i++) {\\n address relayManager = items[i];\\n RelayInfo memory relayInfo = getRelayInfo(relayHub, relayManager);\\n if (\\n relayInfo.lastSeenBlockNumber < oldestBlockNumber ||\\n relayInfo.lastSeenTimestamp < oldestBlockTimestamp\\n ) {\\n continue;\\n }\\n // solhint-disable-next-line no-empty-blocks\\n try IRelayHub(relayHub).verifyRelayManagerStaked(relayManager) {\\n } catch (bytes memory /*lowLevelData*/) {\\n continue;\\n }\\n info[filled++] = relayInfo;\\n if (filled >= maxCount)\\n break;\\n }\\n assembly { mstore(info, filled) }\\n }\\n}\\n\",\"keccak256\":\"0xd03abf65d3eee32b28d8626f62f0f23695eb5fa5150b62e211e639837132602c\",\"license\":\"GPL-3.0-only\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../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 * By default, the owner account will be the one that deploys the contract. This\\n * can 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 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\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 require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\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 require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\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\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.4.22 <0.9.0;\\n\\nlibrary console {\\n address constant CONSOLE_ADDRESS =\\n 0x000000000000000000636F6e736F6c652e6c6f67;\\n\\n function _sendLogPayloadImplementation(bytes memory payload) internal view {\\n address consoleAddress = CONSOLE_ADDRESS;\\n /// @solidity memory-safe-assembly\\n assembly {\\n pop(\\n staticcall(\\n gas(),\\n consoleAddress,\\n add(payload, 32),\\n mload(payload),\\n 0,\\n 0\\n )\\n )\\n }\\n }\\n\\n function _castToPure(\\n function(bytes memory) internal view fnIn\\n ) internal pure returns (function(bytes memory) pure fnOut) {\\n assembly {\\n fnOut := fnIn\\n }\\n }\\n\\n function _sendLogPayload(bytes memory payload) internal pure {\\n _castToPure(_sendLogPayloadImplementation)(payload);\\n }\\n\\n function log() internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n }\\n function logInt(int256 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(int256)\\\", p0));\\n }\\n\\n function logUint(uint256 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n }\\n\\n function logString(string memory p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n }\\n\\n function logBool(bool p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n }\\n\\n function logAddress(address p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n }\\n\\n function logBytes(bytes memory p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n }\\n\\n function logBytes1(bytes1 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n }\\n\\n function logBytes2(bytes2 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n }\\n\\n function logBytes3(bytes3 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n }\\n\\n function logBytes4(bytes4 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n }\\n\\n function logBytes5(bytes5 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n }\\n\\n function logBytes6(bytes6 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n }\\n\\n function logBytes7(bytes7 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n }\\n\\n function logBytes8(bytes8 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n }\\n\\n function logBytes9(bytes9 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n }\\n\\n function logBytes10(bytes10 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n }\\n\\n function logBytes11(bytes11 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n }\\n\\n function logBytes12(bytes12 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n }\\n\\n function logBytes13(bytes13 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n }\\n\\n function logBytes14(bytes14 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n }\\n\\n function logBytes15(bytes15 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n }\\n\\n function logBytes16(bytes16 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n }\\n\\n function logBytes17(bytes17 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n }\\n\\n function logBytes18(bytes18 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n }\\n\\n function logBytes19(bytes19 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n }\\n\\n function logBytes20(bytes20 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n }\\n\\n function logBytes21(bytes21 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n }\\n\\n function logBytes22(bytes22 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n }\\n\\n function logBytes23(bytes23 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n }\\n\\n function logBytes24(bytes24 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n }\\n\\n function logBytes25(bytes25 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n }\\n\\n function logBytes26(bytes26 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n }\\n\\n function logBytes27(bytes27 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n }\\n\\n function logBytes28(bytes28 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n }\\n\\n function logBytes29(bytes29 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n }\\n\\n function logBytes30(bytes30 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n }\\n\\n function logBytes31(bytes31 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n }\\n\\n function logBytes32(bytes32 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n }\\n\\n function log(uint256 p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256)\\\", p0));\\n }\\n\\n function log(string memory p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n }\\n\\n function log(bool p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n }\\n\\n function log(address p0) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n }\\n\\n function log(uint256 p0, uint256 p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256)\\\", p0, p1));\\n }\\n\\n function log(uint256 p0, string memory p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string)\\\", p0, p1));\\n }\\n\\n function log(uint256 p0, bool p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool)\\\", p0, p1));\\n }\\n\\n function log(uint256 p0, address p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address)\\\", p0, p1));\\n }\\n\\n function log(string memory p0, uint256 p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256)\\\", p0, p1));\\n }\\n\\n function log(string memory p0, string memory p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n }\\n\\n function log(string memory p0, bool p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n }\\n\\n function log(string memory p0, address p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n }\\n\\n function log(bool p0, uint256 p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256)\\\", p0, p1));\\n }\\n\\n function log(bool p0, string memory p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n }\\n\\n function log(bool p0, bool p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n }\\n\\n function log(bool p0, address p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n }\\n\\n function log(address p0, uint256 p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256)\\\", p0, p1));\\n }\\n\\n function log(address p0, string memory p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n }\\n\\n function log(address p0, bool p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n }\\n\\n function log(address p0, address p1) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, bool p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, address p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, address p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, string memory p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, bool p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, bool p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, address p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, address p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(string memory p0, address p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, uint256 p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, string memory p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, string memory p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, bool p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, bool p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, bool p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, address p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, address p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, address p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(bool p0, address p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, uint256 p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, uint256 p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, string memory p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, string memory p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, string memory p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, bool p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, bool p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, bool p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, bool p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, address p1, uint256 p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, address p1, string memory p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, address p1, bool p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n }\\n\\n function log(address p0, address p1, address p2) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,uint256,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, string memory p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,string,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, bool p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,bool,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(uint256 p0, address p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(uint256,address,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, uint256 p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint256,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, string memory p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, bool p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(string memory p0, address p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, uint256 p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint256,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, string memory p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, bool p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(bool p0, address p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, uint256 p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint256,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, string memory p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, bool p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, uint256 p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, uint256 p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, uint256 p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint256,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, string memory p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, string memory p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, string memory p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, string memory p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, bool p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, bool p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, bool p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, bool p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, address p2, uint256 p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint256)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, address p2, string memory p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, address p2, bool p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n }\\n\\n function log(address p0, address p1, address p2, address p3) internal pure {\\n _sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n }\\n\\n}\\n\",\"keccak256\":\"0x7434453e6d3b7d0e5d0eb7846ffdbc27f0ccf3b163591263739b628074dc103a\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50604051610d06380380610d0683398101604081905261002f91610108565b6100383361004b565b6100418161009b565b5043608052610121565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6100a36100a8565b600355565b6000546001600160a01b031633146101065760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b565b60006020828403121561011a57600080fd5b5051919050565b608051610bcb61013b600039600060d80152610bcb6000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80638da5cb5b116100715780638da5cb5b14610150578063953f17681461016b578063c240c4561461017e578063e04e5b4f14610191578063f2fde38b14610199578063f999ea82146101ac57600080fd5b806301ffc9a7146100ae57806320ffd56d146100d657806355fb8d6014610106578063715018a61461012657806378ae6b8714610130575b600080fd5b6100c16100bc3660046109f0565b6101bf565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020016100cd565b6101196101143660046109b7565b6101f6565b6040516100cd9190610ac3565b61012e6103cd565b005b61014361013e36600461094a565b6103e1565b6040516100cd9190610b12565b6000546040516001600160a01b0390911681526020016100cd565b61012e61017936600461097d565b610505565b61012e61018c366004610a1a565b6105bc565b6003546100f8565b61012e6101a736600461092f565b6105c9565b6101196101ba36600461092f565b610642565b60006001600160e01b03198216634302517960e01b14806101f057506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001600160a01b038416600090815260026020526040812080546060929084116102205783610223565b81545b67ffffffffffffffff81111561023b5761023b610b7f565b60405190808252806020026020018201604052801561027457816020015b610261610865565b8152602001906001900390816102595790505b50925060005b82548110156103c157600083828154811061029757610297610b69565b60009182526020822001546001600160a01b031691506102b78a836103e1565b905088816000015163ffffffff1610806102db575087816020015164ffffffffff16105b156102e75750506103af565b604051637371170960e11b81526001600160a01b0383811660048301528b169063e6e22e129060240160006040518083038186803b15801561032857600080fd5b505afa925050508015610339575060015b610375573d808015610367576040519150601f19603f3d011682016040523d82523d6000602084013e61036c565b606091505b505050506103af565b80868561038181610b38565b96508151811061039357610393610b69565b60200260200101819052508684106103ac5750506103c1565b50505b806103b981610b38565b91505061027a565b50825250949350505050565b6103d5610682565b6103df60006106dc565b565b6103e9610865565b6001600160a01b0383811660009081526001602081815260408084209487168452938152838320845160c081018652815463ffffffff808216835264ffffffffff6401000000008304811695840195909552600160481b82041682880152600160681b900490921660608084019190915285519081019586905293949193909260808501929084019060039082845b815481526020019060010190808311610478575050509183525050600491909101546001600160a01b0316602090910152805190915063ffffffff166104fe5760405162461bcd60e51b81526020600482015260166024820152751c995b185e53585b9859d95c881b9bdd08199bdd5b9960521b60448201526064015b60405180910390fd5b9392505050565b604051634f7de03160e01b81523360048201819052906001600160a01b03841690634f7de03190602401600060405180830381600087803b15801561054957600080fd5b505af115801561055d573d6000803e3d6000fd5b50505050826001600160a01b0316816001600160a01b03167f46962bfc4fa4f2605ce5867e8135e19bf313555ba5936b9adc4a687ceb3a92ba846040516105a49190610ab0565b60405180910390a36105b781848461072c565b505050565b6105c4610682565b600355565b6105d1610682565b6001600160a01b0381166106365760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104f5565b61063f816106dc565b50565b60606000429050600060035482101561065c576000610669565b6003546106699083610b21565b905061067a846000836103e86101f6565b949350505050565b6000546001600160a01b031633146103df5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104f5565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600061073883856107ed565b8054909150600160481b900463ffffffff1661079057805471ffffffffffffffffff0000000000000000001916600160481b4363ffffffff160264ffffffffff60681b191617600160681b4264ffffffffff16021781555b80544363ffffffff1668ffffffffffffffffff19909116176401000000004264ffffffffff16021781556004810180546001600160a01b0319166001600160a01b0386161790556107e6600182018360036108a2565b5050505050565b6001600160a01b0380831660009081526001602090815260408083209385168352929052908120805463ffffffff166104fe576001600160a01b0393841660009081526002602090815260408220805460018101825590835291200180546001600160a01b0319169390941692909217909255919050565b6040805160c0810182526000808252602082018190529181018290526060810191909152608081016108956108e0565b8152600060209091015290565b82600381019282156108d0579160200282015b828111156108d05782358255916020019190600101906108b5565b506108dc9291506108fe565b5090565b60405180606001604052806003906020820280368337509192915050565b5b808211156108dc57600081556001016108ff565b80356001600160a01b038116811461092a57600080fd5b919050565b60006020828403121561094157600080fd5b6104fe82610913565b6000806040838503121561095d57600080fd5b61096683610913565b915061097460208401610913565b90509250929050565b6000806080838503121561099057600080fd5b61099983610913565b9150836080840111156109ab57600080fd5b50926020919091019150565b600080600080608085870312156109cd57600080fd5b6109d685610913565b966020860135965060408601359560600135945092505050565b600060208284031215610a0257600080fd5b81356001600160e01b0319811681146104fe57600080fd5b600060208284031215610a2c57600080fd5b5035919050565b63ffffffff80825116835260208083015164ffffffffff808216838701528360408601511660408701528060608601511660608701525050608083015191506080840160005b6003811015610a9657835182529282019290820190600101610a79565b5050505060a001516001600160a01b031660e09190910152565b6060818101908383376000815292915050565b6020808252825182820181905260009190848201906040850190845b81811015610b0657610af2838551610a33565b928401926101009290920191600101610adf565b50909695505050505050565b61010081016101f08284610a33565b600082821015610b3357610b33610b53565b500390565b6000600019821415610b4c57610b4c610b53565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea26469706673582212208d9d89b15fca62ff62224e4c3d913c57b2fc45975bbbd1259b9ea9b0d8ad67ed64736f6c63430008070033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a95760003560e01c80638da5cb5b116100715780638da5cb5b14610150578063953f17681461016b578063c240c4561461017e578063e04e5b4f14610191578063f2fde38b14610199578063f999ea82146101ac57600080fd5b806301ffc9a7146100ae57806320ffd56d146100d657806355fb8d6014610106578063715018a61461012657806378ae6b8714610130575b600080fd5b6100c16100bc3660046109f0565b6101bf565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020016100cd565b6101196101143660046109b7565b6101f6565b6040516100cd9190610ac3565b61012e6103cd565b005b61014361013e36600461094a565b6103e1565b6040516100cd9190610b12565b6000546040516001600160a01b0390911681526020016100cd565b61012e61017936600461097d565b610505565b61012e61018c366004610a1a565b6105bc565b6003546100f8565b61012e6101a736600461092f565b6105c9565b6101196101ba36600461092f565b610642565b60006001600160e01b03198216634302517960e01b14806101f057506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001600160a01b038416600090815260026020526040812080546060929084116102205783610223565b81545b67ffffffffffffffff81111561023b5761023b610b7f565b60405190808252806020026020018201604052801561027457816020015b610261610865565b8152602001906001900390816102595790505b50925060005b82548110156103c157600083828154811061029757610297610b69565b60009182526020822001546001600160a01b031691506102b78a836103e1565b905088816000015163ffffffff1610806102db575087816020015164ffffffffff16105b156102e75750506103af565b604051637371170960e11b81526001600160a01b0383811660048301528b169063e6e22e129060240160006040518083038186803b15801561032857600080fd5b505afa925050508015610339575060015b610375573d808015610367576040519150601f19603f3d011682016040523d82523d6000602084013e61036c565b606091505b505050506103af565b80868561038181610b38565b96508151811061039357610393610b69565b60200260200101819052508684106103ac5750506103c1565b50505b806103b981610b38565b91505061027a565b50825250949350505050565b6103d5610682565b6103df60006106dc565b565b6103e9610865565b6001600160a01b0383811660009081526001602081815260408084209487168452938152838320845160c081018652815463ffffffff808216835264ffffffffff6401000000008304811695840195909552600160481b82041682880152600160681b900490921660608084019190915285519081019586905293949193909260808501929084019060039082845b815481526020019060010190808311610478575050509183525050600491909101546001600160a01b0316602090910152805190915063ffffffff166104fe5760405162461bcd60e51b81526020600482015260166024820152751c995b185e53585b9859d95c881b9bdd08199bdd5b9960521b60448201526064015b60405180910390fd5b9392505050565b604051634f7de03160e01b81523360048201819052906001600160a01b03841690634f7de03190602401600060405180830381600087803b15801561054957600080fd5b505af115801561055d573d6000803e3d6000fd5b50505050826001600160a01b0316816001600160a01b03167f46962bfc4fa4f2605ce5867e8135e19bf313555ba5936b9adc4a687ceb3a92ba846040516105a49190610ab0565b60405180910390a36105b781848461072c565b505050565b6105c4610682565b600355565b6105d1610682565b6001600160a01b0381166106365760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104f5565b61063f816106dc565b50565b60606000429050600060035482101561065c576000610669565b6003546106699083610b21565b905061067a846000836103e86101f6565b949350505050565b6000546001600160a01b031633146103df5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104f5565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600061073883856107ed565b8054909150600160481b900463ffffffff1661079057805471ffffffffffffffffff0000000000000000001916600160481b4363ffffffff160264ffffffffff60681b191617600160681b4264ffffffffff16021781555b80544363ffffffff1668ffffffffffffffffff19909116176401000000004264ffffffffff16021781556004810180546001600160a01b0319166001600160a01b0386161790556107e6600182018360036108a2565b5050505050565b6001600160a01b0380831660009081526001602090815260408083209385168352929052908120805463ffffffff166104fe576001600160a01b0393841660009081526002602090815260408220805460018101825590835291200180546001600160a01b0319169390941692909217909255919050565b6040805160c0810182526000808252602082018190529181018290526060810191909152608081016108956108e0565b8152600060209091015290565b82600381019282156108d0579160200282015b828111156108d05782358255916020019190600101906108b5565b506108dc9291506108fe565b5090565b60405180606001604052806003906020820280368337509192915050565b5b808211156108dc57600081556001016108ff565b80356001600160a01b038116811461092a57600080fd5b919050565b60006020828403121561094157600080fd5b6104fe82610913565b6000806040838503121561095d57600080fd5b61096683610913565b915061097460208401610913565b90509250929050565b6000806080838503121561099057600080fd5b61099983610913565b9150836080840111156109ab57600080fd5b50926020919091019150565b600080600080608085870312156109cd57600080fd5b6109d685610913565b966020860135965060408601359560600135945092505050565b600060208284031215610a0257600080fd5b81356001600160e01b0319811681146104fe57600080fd5b600060208284031215610a2c57600080fd5b5035919050565b63ffffffff80825116835260208083015164ffffffffff808216838701528360408601511660408701528060608601511660608701525050608083015191506080840160005b6003811015610a9657835182529282019290820190600101610a79565b5050505060a001516001600160a01b031660e09190910152565b6060818101908383376000815292915050565b6020808252825182820181905260009190848201906040850190845b81811015610b0657610af2838551610a33565b928401926101009290920191600101610adf565b50909695505050505050565b61010081016101f08284610a33565b600082821015610b3357610b33610b53565b500390565b6000600019821415610b4c57610b4c610b53565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea26469706673582212208d9d89b15fca62ff62224e4c3d913c57b2fc45975bbbd1259b9ea9b0d8ad67ed64736f6c63430008070033", + "devdoc": { + "kind": "dev", + "methods": { + "getCreationBlock()": { + "returns": { + "_0": "The block number in which the contract has been deployed." + } + }, + "getRelayInfo(address,address)": { + "params": { + "relayHub": "The address of the `RelayHub` contract for which this action is performed.", + "relayManager": "An address of a Relay Manager." + }, + "returns": { + "_0": "All the details of the given Relay Manager's registration. Throws if relay not found for `RelayHub`." + } + }, + "getRelayRegistrationMaxAge()": { + "returns": { + "_0": "The maximum age the relay is considered registered by default by this `RelayRegistrar`, in seconds." + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "readRelayInfos(address)": { + "params": { + "relayHub": "The address of the `RelayHub` contract for which this action is performed." + }, + "returns": { + "info": "The list of `RelayInfo`s of registered Relay Servers" + } + }, + "readRelayInfosInRange(address,uint256,uint256,uint256)": { + "params": { + "maxCount": "The maximum amount of relays to be returned by this function.", + "oldestBlockNumber": "The latest block number in which a Relay Server may be registered.", + "oldestBlockTimestamp": "The latest block timestamp in which a Relay Server may be registered.", + "relayHub": "The address of the `RelayHub` contract for which this action is performed." + }, + "returns": { + "info": "The list of `RelayInfo`s of registered Relay Servers" + } + }, + "registerRelayServer(address,bytes32[3])": { + "params": { + "relayHub": "The address of the `RelayHub` contract for which this action is performed.", + "url": "The URL of the Relay Server that is listening to the clients' requests." + } + }, + "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." + }, + "supportsInterface(bytes4)": { + "details": "Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "title": "The RelayRegistrar Implementation", + "version": 1 + }, + "userdoc": { + "events": { + "RelayServerRegistered(address,address,bytes32[3])": { + "notice": "Emitted when a relay server registers or updates its details. Looking up these events allows a client to discover registered Relay Servers." + } + }, + "kind": "user", + "methods": { + "readRelayInfos(address)": { + "notice": "Read relay info of registered Relay Server from an on-chain storage." + }, + "readRelayInfosInRange(address,uint256,uint256,uint256)": { + "notice": "Read relay info of registered Relay Server from an on-chain storage." + }, + "registerRelayServer(address,bytes32[3])": { + "notice": "This function is called by Relay Servers in order to register or to update their registration." + }, + "setRelayRegistrationMaxAge(uint256)": { + "notice": "Change the maximum relay registration age." + } + }, + "notice": "Keeps a list of registered relayers.Provides view functions to read the list of registered relayers and filters out invalid ones.Protects the list from spamming entries: only staked relayers are added.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 8589, + "contract": "@opengsn/contracts/src/utils/RelayRegistrar.sol:RelayRegistrar", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 8167, + "contract": "@opengsn/contracts/src/utils/RelayRegistrar.sol:RelayRegistrar", + "label": "values", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_struct(RelayInfo)5527_storage))" + }, + { + "astId": 8173, + "contract": "@opengsn/contracts/src/utils/RelayRegistrar.sol:RelayRegistrar", + "label": "indexedValues", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_array(t_address)dyn_storage)" + }, + { + "astId": 8177, + "contract": "@opengsn/contracts/src/utils/RelayRegistrar.sol:RelayRegistrar", + "label": "relayRegistrationMaxAge", + "offset": 0, + "slot": "3", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_address)dyn_storage": { + "base": "t_address", + "encoding": "dynamic_array", + "label": "address[]", + "numberOfBytes": "32" + }, + "t_array(t_bytes32)3_storage": { + "base": "t_bytes32", + "encoding": "inplace", + "label": "bytes32[3]", + "numberOfBytes": "96" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_array(t_address)dyn_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address[])", + "numberOfBytes": "32", + "value": "t_array(t_address)dyn_storage" + }, + "t_mapping(t_address,t_mapping(t_address,t_struct(RelayInfo)5527_storage))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => struct IRelayRegistrar.RelayInfo))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_struct(RelayInfo)5527_storage)" + }, + "t_mapping(t_address,t_struct(RelayInfo)5527_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct IRelayRegistrar.RelayInfo)", + "numberOfBytes": "32", + "value": "t_struct(RelayInfo)5527_storage" + }, + "t_struct(RelayInfo)5527_storage": { + "encoding": "inplace", + "label": "struct IRelayRegistrar.RelayInfo", + "members": [ + { + "astId": 5514, + "contract": "@opengsn/contracts/src/utils/RelayRegistrar.sol:RelayRegistrar", + "label": "lastSeenBlockNumber", + "offset": 0, + "slot": "0", + "type": "t_uint32" + }, + { + "astId": 5516, + "contract": "@opengsn/contracts/src/utils/RelayRegistrar.sol:RelayRegistrar", + "label": "lastSeenTimestamp", + "offset": 4, + "slot": "0", + "type": "t_uint40" + }, + { + "astId": 5518, + "contract": "@opengsn/contracts/src/utils/RelayRegistrar.sol:RelayRegistrar", + "label": "firstSeenBlockNumber", + "offset": 9, + "slot": "0", + "type": "t_uint32" + }, + { + "astId": 5520, + "contract": "@opengsn/contracts/src/utils/RelayRegistrar.sol:RelayRegistrar", + "label": "firstSeenTimestamp", + "offset": 13, + "slot": "0", + "type": "t_uint40" + }, + { + "astId": 5524, + "contract": "@opengsn/contracts/src/utils/RelayRegistrar.sol:RelayRegistrar", + "label": "urlParts", + "offset": 0, + "slot": "1", + "type": "t_array(t_bytes32)3_storage" + }, + { + "astId": 5526, + "contract": "@opengsn/contracts/src/utils/RelayRegistrar.sol:RelayRegistrar", + "label": "relayManager", + "offset": 0, + "slot": "4", + "type": "t_address" + } + ], + "numberOfBytes": "160" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "encoding": "inplace", + "label": "uint32", + "numberOfBytes": "4" + }, + "t_uint40": { + "encoding": "inplace", + "label": "uint40", + "numberOfBytes": "5" + } + } + } +} \ No newline at end of file diff --git a/gsn/deploy/data/deployments/amoy/StakeManager.json b/gsn/deploy/data/deployments/amoy/StakeManager.json new file mode 100644 index 00000000..46407af4 --- /dev/null +++ b/gsn/deploy/data/deployments/amoy/StakeManager.json @@ -0,0 +1,1326 @@ +{ + "address": "0x542B24678Ee3c319EBE006aD677cf8Ce4C6F97b0", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxUnstakeDelay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_abandonmentDelay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_escheatmentDelay", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_burnAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_devAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AbandonedRelayManagerStakeEscheated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "burnAddress", + "type": "address" + } + ], + "name": "BurnAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "devAddress", + "type": "address" + } + ], + "name": "DevAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "relayHub", + "type": "address" + } + ], + "name": "HubAuthorized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "relayHub", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "removalTime", + "type": "uint256" + } + ], + "name": "HubUnauthorized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "abandonedTime", + "type": "uint256" + } + ], + "name": "RelayServerAbandoned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "keepaliveTime", + "type": "uint256" + } + ], + "name": "RelayServerKeepalive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stake", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "unstakeDelay", + "type": "uint256" + } + ], + "name": "StakeAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "StakePenalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawTime", + "type": "uint256" + } + ], + "name": "StakeUnlocked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "StakeWithdrawn", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayHub", + "type": "address" + } + ], + "name": "authorizeHubByManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "internalType": "address", + "name": "relayHub", + "type": "address" + } + ], + "name": "authorizeHubByOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "authorizedHubs", + "outputs": [ + { + "internalType": "uint256", + "name": "removalTime", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "name": "escheatAbandonedRelayStake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAbandonedRelayServerConfig", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "devAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "abandonmentDelay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "escheatmentDelay", + "type": "uint256" + } + ], + "internalType": "struct IStakeManager.AbandonedRelayServerConfig", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBurnAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCreationBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMaxUnstakeDelay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "name": "getStakeInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "stake", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "unstakeDelay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "withdrawTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "abandonedTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "keepaliveTime", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "internalType": "struct IStakeManager.StakeInfo", + "name": "stakeInfo", + "type": "tuple" + }, + { + "internalType": "bool", + "name": "isSenderAuthorizedHub", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "name": "isRelayEscheatable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "name": "markRelayAbandoned", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "penalizeRelayManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_burnAddress", + "type": "address" + } + ], + "name": "setBurnAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_devAddress", + "type": "address" + } + ], + "name": "setDevAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "setRelayManagerOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "internalType": "uint256", + "name": "unstakeDelay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "stakeForRelayManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "stakes", + "outputs": [ + { + "internalType": "uint256", + "name": "stake", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "unstakeDelay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "withdrawTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "abandonedTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "keepaliveTime", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayHub", + "type": "address" + } + ], + "name": "unauthorizeHubByManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + }, + { + "internalType": "address", + "name": "relayHub", + "type": "address" + } + ], + "name": "unauthorizeHubByOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "name": "unlockStake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "name": "updateRelayKeepaliveTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "versionSM", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "relayManager", + "type": "address" + } + ], + "name": "withdrawStake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x71b42cd60cd3df9c9f59e7adfb10e5cf3287034be3c514425e964ef802f4b54b", + "receipt": { + "to": null, + "from": "0x61B1E290d2F465d6667336d4934941aa2517AfA2", + "contractAddress": "0x542B24678Ee3c319EBE006aD677cf8Ce4C6F97b0", + "transactionIndex": 0, + "gasUsed": "1882369", + "logsBloom": "0x00000004000000800008000000000000000000000000000000800000000000000000000000000002000000000000000000008000000000000000000000000000044000000000000000000000000000800001000000000000000100000000000000000010020000000000000000000800000000000000000080000000000000400000000000000000000000002000000001000000000000000000000000000000200008000000000000000000000000000020000000000000000000000000104000000000000000008001000000000000000000000002400000100000000020000000000000080000000000000800000000000000000000000000000000100000", + "blockHash": "0xdffa7dc6f6ac99674297e4b6f2cad7cb5b44cb055c4242cd82aa548ededc8aa7", + "transactionHash": "0x71b42cd60cd3df9c9f59e7adfb10e5cf3287034be3c514425e964ef802f4b54b", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 4880204, + "transactionHash": "0x71b42cd60cd3df9c9f59e7adfb10e5cf3287034be3c514425e964ef802f4b54b", + "address": "0x542B24678Ee3c319EBE006aD677cf8Ce4C6F97b0", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000061b1e290d2f465d6667336d4934941aa2517afa2" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xdffa7dc6f6ac99674297e4b6f2cad7cb5b44cb055c4242cd82aa548ededc8aa7" + }, + { + "transactionIndex": 0, + "blockNumber": 4880204, + "transactionHash": "0x71b42cd60cd3df9c9f59e7adfb10e5cf3287034be3c514425e964ef802f4b54b", + "address": "0x542B24678Ee3c319EBE006aD677cf8Ce4C6F97b0", + "topics": [ + "0xb0d2ad16ddd4d3dd008ebff0b7e7699bbfa920003cb0764acb871951d1cd4999", + "0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0xdffa7dc6f6ac99674297e4b6f2cad7cb5b44cb055c4242cd82aa548ededc8aa7" + }, + { + "transactionIndex": 0, + "blockNumber": 4880204, + "transactionHash": "0x71b42cd60cd3df9c9f59e7adfb10e5cf3287034be3c514425e964ef802f4b54b", + "address": "0x542B24678Ee3c319EBE006aD677cf8Ce4C6F97b0", + "topics": [ + "0x78ef0ef64366f55e36ce7c04060e8bc5846d3651c53909eafc38458922d8a879", + "0x00000000000000000000000061b1e290d2f465d6667336d4934941aa2517afa2" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0xdffa7dc6f6ac99674297e4b6f2cad7cb5b44cb055c4242cd82aa548ededc8aa7" + }, + { + "transactionIndex": 0, + "blockNumber": 4880204, + "transactionHash": "0x71b42cd60cd3df9c9f59e7adfb10e5cf3287034be3c514425e964ef802f4b54b", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x00000000000000000000000061b1e290d2f465d6667336d4934941aa2517afa2", + "0x000000000000000000000000ac75d6efec891724b88b916b36e2ef38bcbec73f" + ], + "data": "0x00000000000000000000000000000000000000000000000001914047253080f100000000000000000000000000000000000000000000000003d057d76b56400000000000000000000000000000000000000000000000001747e62692c188ed11000000000000000000000000000000000000000000000000023f17904625bf0f000000000000000000000000000000000000000000000017497766d9e6b96e02", + "logIndex": 3, + "blockHash": "0xdffa7dc6f6ac99674297e4b6f2cad7cb5b44cb055c4242cd82aa548ededc8aa7" + } + ], + "blockNumber": 4880204, + "cumulativeGasUsed": "1882369", + "status": 1, + "byzantium": true + }, + "args": [ + 100000000, + 31536000, + 2629746, + "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", + "0x61B1E290d2F465d6667336d4934941aa2517AfA2" + ], + "numDeployments": 1, + "solcInputHash": "766eaa539015b343a6f8732a84d5a9ae", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxUnstakeDelay\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_abandonmentDelay\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_escheatmentDelay\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_burnAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_devAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"AbandonedRelayManagerStakeEscheated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"burnAddress\",\"type\":\"address\"}],\"name\":\"BurnAddressSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"devAddress\",\"type\":\"address\"}],\"name\":\"DevAddressSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayHub\",\"type\":\"address\"}],\"name\":\"HubAuthorized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayHub\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"removalTime\",\"type\":\"uint256\"}],\"name\":\"HubUnauthorized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"abandonedTime\",\"type\":\"uint256\"}],\"name\":\"RelayServerAbandoned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"keepaliveTime\",\"type\":\"uint256\"}],\"name\":\"RelayServerKeepalive\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelay\",\"type\":\"uint256\"}],\"name\":\"StakeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"}],\"name\":\"StakePenalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"}],\"name\":\"StakeUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"StakeWithdrawn\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayHub\",\"type\":\"address\"}],\"name\":\"authorizeHubByManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"relayHub\",\"type\":\"address\"}],\"name\":\"authorizeHubByOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"authorizedHubs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"removalTime\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"name\":\"escheatAbandonedRelayStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAbandonedRelayServerConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"devAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"abandonmentDelay\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"escheatmentDelay\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.AbandonedRelayServerConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBurnAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreationBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMaxUnstakeDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"name\":\"getStakeInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelay\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"abandonedTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"keepaliveTime\",\"type\":\"uint256\"},{\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"stakeInfo\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"isSenderAuthorizedHub\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"name\":\"isRelayEscheatable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"name\":\"markRelayAbandoned\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"penalizeRelayManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_burnAddress\",\"type\":\"address\"}],\"name\":\"setBurnAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_devAddress\",\"type\":\"address\"}],\"name\":\"setDevAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"setRelayManagerOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelay\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"stakeForRelayManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"stakes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelay\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"abandonedTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"keepaliveTime\",\"type\":\"uint256\"},{\"internalType\":\"contract IERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayHub\",\"type\":\"address\"}],\"name\":\"unauthorizeHubByManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"relayHub\",\"type\":\"address\"}],\"name\":\"unauthorizeHubByOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"name\":\"unlockStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"name\":\"updateRelayKeepaliveTime\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"versionSM\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayManager\",\"type\":\"address\"}],\"name\":\"withdrawStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"authorizeHubByOwner(address,address)\":{\"params\":{\"relayHub\":\"The address of a `RelayHub` to be authorized.\",\"relayManager\":\"The address of a Relay Manager whose stake is to be authorized for the new `RelayHub`.\"}},\"getAbandonedRelayServerConfig()\":{\"returns\":{\"_0\":\"The structure that contains all configuration values for the 'abandoned' stake.\"}},\"getBurnAddress()\":{\"returns\":{\"_0\":\"The address that will receive the 'burned' part of the penalized stake.\"}},\"getCreationBlock()\":{\"returns\":{\"_0\":\"the block number in which the contract has been deployed.\"}},\"getMaxUnstakeDelay()\":{\"returns\":{\"_0\":\"The maximum unstake delay this `StakeManger` allows. This is to prevent locking money forever by mistake.\"}},\"getStakeInfo(address)\":{\"params\":{\"relayManager\":\"The address of a Relay Manager.\"},\"returns\":{\"isSenderAuthorizedHub\":\"`true` if the `msg.sender` for this call was a `RelayHub` that is authorized now. `false` if the `msg.sender` for this call is not authorized.\",\"stakeInfo\":\"The `StakeInfo` structure.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"penalizeRelayManager(address,address,uint256)\":{\"params\":{\"amount\":\"A total amount of penalty to be withdrawn from stake.\",\"beneficiary\":\"The address that receives part of the penalty amount.\",\"relayManager\":\"The address of a Relay Manager to be penalized.\"}},\"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.\"},\"setRelayManagerOwner(address)\":{\"params\":{\"owner\":\"- owner of the relay (as configured off-chain)\"}},\"stakeForRelayManager(address,address,uint256,uint256)\":{\"params\":{\"amount\":\"The amount of tokens to be taken from the relayOwner and locked in the StakeManager as a stake\",\"relayManager\":\"The address that represents a stake entry and controls relay registrations on relay hubs\",\"token\":\"The address of an ERC-20 token that is used by the relayManager as a stake\",\"unstakeDelay\":\"The number of seconds to elapse before an owner can retrieve the stake after calling `unlock`\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unauthorizeHubByOwner(address,address)\":{\"params\":{\"relayHub\":\"The address of a `RelayHub` to be unauthorized.\",\"relayManager\":\"The address of a Relay Manager.\"}},\"unlockStake(address)\":{\"params\":{\"relayManager\":\"The address of a Relay Manager whose stake is to be unlocked.\"}},\"withdrawStake(address)\":{\"params\":{\"relayManager\":\"The address of a Relay Manager whose stake is to be withdrawn.\"}}},\"stateVariables\":{\"versionSM\":{\"return\":\"a SemVer-compliant version of the `StakeManager` contract.\",\"returns\":{\"_0\":\"a SemVer-compliant version of the `StakeManager` contract.\"}}},\"title\":\"The StakeManager implementation\",\"version\":1},\"userdoc\":{\"events\":{\"AbandonedRelayManagerStakeEscheated(address,address,address,uint256)\":{\"notice\":\"Emitted when the stake of an abandoned relayer has been confiscated and transferred to the `devAddress`.\"},\"BurnAddressSet(address)\":{\"notice\":\"Emitted when a `burnAddress` is changed.\"},\"DevAddressSet(address)\":{\"notice\":\"Emitted when a `devAddress` is changed.\"},\"HubAuthorized(address,address)\":{\"notice\":\"Emitted when a `relayManager` adds a new `RelayHub` to a list of authorized.\"},\"HubUnauthorized(address,address,uint256)\":{\"notice\":\"Emitted when a `relayManager` removes a `RelayHub` from a list of authorized.\"},\"OwnerSet(address,address)\":{\"notice\":\"Emitted when a `relayManager` sets its `owner`. This is necessary to prevent stake hijacking.\"},\"RelayServerAbandoned(address,uint256)\":{\"notice\":\"Emitted if Relay Server is inactive for an `abandonmentDelay` and contract owner initiates its removal.\"},\"RelayServerKeepalive(address,uint256)\":{\"notice\":\"Emitted to indicate an action performed by a relay server to prevent it from being marked as abandoned.\"},\"StakeAdded(address,address,address,uint256,uint256)\":{\"notice\":\"Emitted when a `stake` or `unstakeDelay` are initialized or increased.\"},\"StakePenalized(address,address,address,uint256)\":{\"notice\":\"Emitted when an authorized `RelayHub` penalizes a `relayManager`.\"},\"StakeUnlocked(address,address,uint256)\":{\"notice\":\"Emitted once a stake is scheduled for withdrawal.\"},\"StakeWithdrawn(address,address,address,uint256)\":{\"notice\":\"Emitted when owner withdraws `relayManager` funds.\"}},\"kind\":\"user\",\"methods\":{\"authorizeHubByManager(address)\":{\"notice\":\"Same as `authorizeHubByOwner` but can be called by the RelayManager itself.\"},\"authorizeHubByOwner(address,address)\":{\"notice\":\"Add the `RelayHub` to a list of authorized by this Relay Manager. This allows the RelayHub to penalize this Relay Manager. The `RelayHub` cannot trust a Relay it cannot penalize.\"},\"authorizedHubs(address,address)\":{\"notice\":\"maps relay managers to a map of addressed of their authorized hubs to the information on that hub\"},\"escheatAbandonedRelayStake(address)\":{\"notice\":\"If more than `abandonmentDelay` has passed since the last Keepalive transaction, and relay manager has been marked as abandoned, and after that more that `escheatmentDelay` have passed, entire stake and balance will be taken from this relay.\"},\"getStakeInfo(address)\":{\"notice\":\"Get the stake details information for the given Relay Manager.\"},\"isRelayEscheatable(address)\":{\"notice\":\"Check if the Relay Manager can be considered abandoned or not. Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\"},\"markRelayAbandoned(address)\":{\"notice\":\"Allows the contract owner to set the given `relayManager` as abandoned after a configurable delay. Its entire stake and balance will be taken from a relay if it does not respond to being marked as abandoned.\"},\"penalizeRelayManager(address,address,uint256)\":{\"notice\":\"Slash the stake of the relay relayManager. In order to prevent stake kidnapping, burns part of stake on the way.\"},\"setBurnAddress(address)\":{\"notice\":\"Change the address that will receive the 'burned' part of the penalized stake. This is done to prevent malicious Relay Server from penalizing itself and breaking even.\"},\"setDevAddress(address)\":{\"notice\":\"Change the address that will receive the 'abandoned' stake. This is done to prevent Relay Servers that lost their keys from losing access to funds.\"},\"setRelayManagerOwner(address)\":{\"notice\":\"Set the owner of a Relay Manager. Called only by the RelayManager itself. Note that owners cannot transfer ownership - if the entry already exists, reverts.\"},\"stakeForRelayManager(address,address,uint256,uint256)\":{\"notice\":\"Put a stake for a relayManager and set its unstake delay. Only the owner can call this function. If the entry does not exist, reverts. The owner must give allowance of the ERC-20 token to the StakeManager before calling this method. It is the RelayHub who has a configurable list of minimum stakes per token. StakeManager accepts all tokens.\"},\"stakes(address)\":{\"notice\":\"maps relay managers to their stakes\"},\"unauthorizeHubByManager(address)\":{\"notice\":\"Same as `unauthorizeHubByOwner` but can be called by the RelayManager itself.\"},\"unauthorizeHubByOwner(address,address)\":{\"notice\":\"Remove the `RelayHub` from a list of authorized by this Relay Manager.\"},\"unlockStake(address)\":{\"notice\":\"Schedule the unlocking of the stake. The `unstakeDelay` must pass before owner can call `withdrawStake`.\"},\"updateRelayKeepaliveTime(address)\":{\"notice\":\"Sets a new `keepaliveTime` for the given `relayManager`, preventing it from being marked as abandoned. Can be called by an authorized `RelayHub` or by the `relayOwner` address.\"},\"withdrawStake(address)\":{\"notice\":\"Withdraw the unlocked stake.\"}},\"notice\":\"An IStakeManager instance that accepts stakes in any ERC-20 token.Single StakeInfo of a single RelayManager can only have one token address assigned to it.It cannot be changed after the first time 'stakeForRelayManager' is called as it is equivalent to withdrawal.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@opengsn/contracts/src/StakeManager.sol\":\"StakeManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@opengsn/contracts/src/StakeManager.sol\":{\"content\":\"// solhint-disable not-rely-on-time\\n// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.0;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\n\\nimport \\\"./interfaces/IStakeManager.sol\\\";\\n\\n/**\\n * @title The StakeManager implementation\\n * @notice An IStakeManager instance that accepts stakes in any ERC-20 token.\\n *\\n * @notice Single StakeInfo of a single RelayManager can only have one token address assigned to it.\\n *\\n * @notice It cannot be changed after the first time 'stakeForRelayManager' is called as it is equivalent to withdrawal.\\n */\\ncontract StakeManager is IStakeManager, Ownable, ERC165 {\\n using SafeERC20 for IERC20;\\n\\n string public override versionSM = \\\"3.0.0-beta.3+opengsn.stakemanager.istakemanager\\\";\\n uint256 internal immutable maxUnstakeDelay;\\n\\n AbandonedRelayServerConfig internal abandonedRelayServerConfig;\\n\\n address internal burnAddress;\\n uint256 internal immutable creationBlock;\\n\\n /// maps relay managers to their stakes\\n mapping(address => StakeInfo) public stakes;\\n\\n /// @inheritdoc IStakeManager\\n function getStakeInfo(address relayManager) external override view returns (StakeInfo memory stakeInfo, bool isSenderAuthorizedHub) {\\n bool isHubAuthorized = authorizedHubs[relayManager][msg.sender].removalTime == type(uint256).max;\\n return (stakes[relayManager], isHubAuthorized);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function setBurnAddress(address _burnAddress) public override onlyOwner {\\n burnAddress = _burnAddress;\\n emit BurnAddressSet(burnAddress);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function getBurnAddress() external override view returns (address) {\\n return burnAddress;\\n }\\n\\n /// @inheritdoc IStakeManager\\n function setDevAddress(address _devAddress) public override onlyOwner {\\n abandonedRelayServerConfig.devAddress = _devAddress;\\n emit DevAddressSet(abandonedRelayServerConfig.devAddress);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function getAbandonedRelayServerConfig() external override view returns (AbandonedRelayServerConfig memory) {\\n return abandonedRelayServerConfig;\\n }\\n\\n /// @inheritdoc IStakeManager\\n function getMaxUnstakeDelay() external override view returns (uint256) {\\n return maxUnstakeDelay;\\n }\\n\\n /// maps relay managers to a map of addressed of their authorized hubs to the information on that hub\\n mapping(address => mapping(address => RelayHubInfo)) public authorizedHubs;\\n\\n constructor(\\n uint256 _maxUnstakeDelay,\\n uint256 _abandonmentDelay,\\n uint256 _escheatmentDelay,\\n address _burnAddress,\\n address _devAddress\\n ) {\\n require(_burnAddress != address(0), \\\"transfers to address(0) may fail\\\");\\n setBurnAddress(_burnAddress);\\n setDevAddress(_devAddress);\\n creationBlock = block.number;\\n maxUnstakeDelay = _maxUnstakeDelay;\\n abandonedRelayServerConfig.abandonmentDelay = _abandonmentDelay;\\n abandonedRelayServerConfig.escheatmentDelay = _escheatmentDelay;\\n }\\n\\n /// @inheritdoc IERC165\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\\n return interfaceId == type(IStakeManager).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function getCreationBlock() external override view returns (uint256){\\n return creationBlock;\\n }\\n\\n /// @inheritdoc IStakeManager\\n function setRelayManagerOwner(address owner) external override {\\n require(owner != address(0), \\\"invalid owner\\\");\\n require(stakes[msg.sender].owner == address(0), \\\"already owned\\\");\\n stakes[msg.sender].owner = owner;\\n emit OwnerSet(msg.sender, owner);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function stakeForRelayManager(IERC20 token, address relayManager, uint256 unstakeDelay, uint256 amount) external override relayOwnerOnly(relayManager) {\\n require(unstakeDelay >= stakes[relayManager].unstakeDelay, \\\"unstakeDelay cannot be decreased\\\");\\n require(unstakeDelay <= maxUnstakeDelay, \\\"unstakeDelay too big\\\");\\n require(token != IERC20(address(0)), \\\"must specify stake token address\\\");\\n require(\\n stakes[relayManager].token == IERC20(address(0)) ||\\n stakes[relayManager].token == token,\\n \\\"stake token address is incorrect\\\");\\n token.safeTransferFrom(msg.sender, address(this), amount);\\n stakes[relayManager].token = token;\\n stakes[relayManager].stake += amount;\\n stakes[relayManager].unstakeDelay = unstakeDelay;\\n emit StakeAdded(relayManager, stakes[relayManager].owner, stakes[relayManager].token, stakes[relayManager].stake, stakes[relayManager].unstakeDelay);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function unlockStake(address relayManager) external override relayOwnerOnly(relayManager) {\\n StakeInfo storage info = stakes[relayManager];\\n require(info.withdrawTime == 0, \\\"already pending\\\");\\n info.withdrawTime = block.timestamp + info.unstakeDelay;\\n emit StakeUnlocked(relayManager, msg.sender, info.withdrawTime);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function withdrawStake(address relayManager) external override relayOwnerOnly(relayManager) {\\n StakeInfo storage info = stakes[relayManager];\\n require(info.withdrawTime > 0, \\\"Withdrawal is not scheduled\\\");\\n require(info.withdrawTime <= block.timestamp, \\\"Withdrawal is not due\\\");\\n uint256 amount = info.stake;\\n info.stake = 0;\\n info.withdrawTime = 0;\\n info.token.safeTransfer(msg.sender, amount);\\n emit StakeWithdrawn(relayManager, msg.sender, info.token, amount);\\n }\\n\\n /// @notice Prevents any address other than a registered Relay Owner from calling this method.\\n modifier relayOwnerOnly (address relayManager) {\\n StakeInfo storage info = stakes[relayManager];\\n require(info.owner == msg.sender, \\\"not owner\\\");\\n _;\\n }\\n\\n /// @notice Prevents any address other than a registered Relay Manager from calling this method.\\n modifier managerOnly () {\\n StakeInfo storage info = stakes[msg.sender];\\n require(info.owner != address(0), \\\"not manager\\\");\\n _;\\n }\\n\\n /// @inheritdoc IStakeManager\\n function authorizeHubByOwner(address relayManager, address relayHub) external relayOwnerOnly(relayManager) override {\\n _authorizeHub(relayManager, relayHub);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function authorizeHubByManager(address relayHub) external managerOnly override {\\n _authorizeHub(msg.sender, relayHub);\\n }\\n\\n function _authorizeHub(address relayManager, address relayHub) internal {\\n authorizedHubs[relayManager][relayHub].removalTime = type(uint256).max;\\n emit HubAuthorized(relayManager, relayHub);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function unauthorizeHubByOwner(address relayManager, address relayHub) external override relayOwnerOnly(relayManager) {\\n _unauthorizeHub(relayManager, relayHub);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function unauthorizeHubByManager(address relayHub) external override managerOnly {\\n _unauthorizeHub(msg.sender, relayHub);\\n }\\n\\n function _unauthorizeHub(address relayManager, address relayHub) internal {\\n RelayHubInfo storage hubInfo = authorizedHubs[relayManager][relayHub];\\n require(hubInfo.removalTime == type(uint256).max, \\\"hub not authorized\\\");\\n hubInfo.removalTime = block.timestamp + stakes[relayManager].unstakeDelay;\\n emit HubUnauthorized(relayManager, relayHub, hubInfo.removalTime);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function penalizeRelayManager(address relayManager, address beneficiary, uint256 amount) external override {\\n uint256 removalTime = authorizedHubs[relayManager][msg.sender].removalTime;\\n require(removalTime != 0, \\\"hub not authorized\\\");\\n require(removalTime > block.timestamp, \\\"hub authorization expired\\\");\\n\\n // Half of the stake will be burned (sent to address 0)\\n require(stakes[relayManager].stake >= amount, \\\"penalty exceeds stake\\\");\\n stakes[relayManager].stake =stakes[relayManager].stake - amount;\\n\\n uint256 toBurn = amount / 2;\\n uint256 reward = amount - toBurn;\\n\\n // Stake ERC-20 token is burned and transferred\\n stakes[relayManager].token.safeTransfer(burnAddress, toBurn);\\n stakes[relayManager].token.safeTransfer(beneficiary, reward);\\n emit StakePenalized(relayManager, beneficiary, stakes[relayManager].token, reward);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function isRelayEscheatable(address relayManager) public view override returns (bool) {\\n IStakeManager.StakeInfo memory stakeInfo = stakes[relayManager];\\n return stakeInfo.abandonedTime != 0 && stakeInfo.abandonedTime + abandonedRelayServerConfig.escheatmentDelay < block.timestamp;\\n }\\n\\n /// @inheritdoc IStakeManager\\n function markRelayAbandoned(address relayManager) external override onlyOwner {\\n StakeInfo storage info = stakes[relayManager];\\n require(info.stake > 0, \\\"relay manager not staked\\\");\\n require(info.abandonedTime == 0, \\\"relay manager already abandoned\\\");\\n require(info.keepaliveTime + abandonedRelayServerConfig.abandonmentDelay < block.timestamp, \\\"relay manager was alive recently\\\");\\n info.abandonedTime = block.timestamp;\\n emit RelayServerAbandoned(relayManager, info.abandonedTime);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function escheatAbandonedRelayStake(address relayManager) external override onlyOwner {\\n StakeInfo storage info = stakes[relayManager];\\n require(isRelayEscheatable(relayManager), \\\"relay server not escheatable yet\\\");\\n uint256 amount = info.stake;\\n info.stake = 0;\\n info.withdrawTime = 0;\\n info.token.safeTransfer(abandonedRelayServerConfig.devAddress, amount);\\n emit AbandonedRelayManagerStakeEscheated(relayManager, msg.sender, info.token, amount);\\n }\\n\\n /// @inheritdoc IStakeManager\\n function updateRelayKeepaliveTime(address relayManager) external override {\\n StakeInfo storage info = stakes[relayManager];\\n bool isHubAuthorized = authorizedHubs[relayManager][msg.sender].removalTime == type(uint256).max;\\n bool isRelayOwner = info.owner == msg.sender;\\n require(isHubAuthorized || isRelayOwner, \\\"must be called by owner or hub\\\");\\n info.abandonedTime = 0;\\n info.keepaliveTime = block.timestamp;\\n emit RelayServerKeepalive(relayManager, info.keepaliveTime);\\n }\\n}\\n\",\"keccak256\":\"0x4d2ed3c27408862e42b00c8ec1d6c3231759b5932a71bb71ff84805a4f48f467\",\"license\":\"GPL-3.0-only\"},\"@opengsn/contracts/src/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @title The StakeManager Interface\\n * @notice In order to prevent an attacker from registering a large number of unresponsive relays, the GSN requires\\n * the Relay Server to maintain a permanently locked stake in the system before being able to register.\\n *\\n * @notice Also, in some cases the behavior of a Relay Server may be found to be illegal by a `Penalizer` contract.\\n * In such case, the stake will never be returned to the Relay Server operator and will be slashed.\\n *\\n * @notice An implementation of this interface is tasked with keeping Relay Servers' stakes, made in any ERC-20 token.\\n * Note that the `RelayHub` chooses which ERC-20 tokens to support and how much stake is needed.\\n */\\ninterface IStakeManager is IERC165 {\\n\\n /// @notice Emitted when a `stake` or `unstakeDelay` are initialized or increased.\\n event StakeAdded(\\n address indexed relayManager,\\n address indexed owner,\\n IERC20 token,\\n uint256 stake,\\n uint256 unstakeDelay\\n );\\n\\n /// @notice Emitted once a stake is scheduled for withdrawal.\\n event StakeUnlocked(\\n address indexed relayManager,\\n address indexed owner,\\n uint256 withdrawTime\\n );\\n\\n /// @notice Emitted when owner withdraws `relayManager` funds.\\n event StakeWithdrawn(\\n address indexed relayManager,\\n address indexed owner,\\n IERC20 token,\\n uint256 amount\\n );\\n\\n /// @notice Emitted when an authorized `RelayHub` penalizes a `relayManager`.\\n event StakePenalized(\\n address indexed relayManager,\\n address indexed beneficiary,\\n IERC20 token,\\n uint256 reward\\n );\\n\\n /// @notice Emitted when a `relayManager` adds a new `RelayHub` to a list of authorized.\\n event HubAuthorized(\\n address indexed relayManager,\\n address indexed relayHub\\n );\\n\\n /// @notice Emitted when a `relayManager` removes a `RelayHub` from a list of authorized.\\n event HubUnauthorized(\\n address indexed relayManager,\\n address indexed relayHub,\\n uint256 removalTime\\n );\\n\\n /// @notice Emitted when a `relayManager` sets its `owner`. This is necessary to prevent stake hijacking.\\n event OwnerSet(\\n address indexed relayManager,\\n address indexed owner\\n );\\n\\n /// @notice Emitted when a `burnAddress` is changed.\\n event BurnAddressSet(\\n address indexed burnAddress\\n );\\n\\n /// @notice Emitted when a `devAddress` is changed.\\n event DevAddressSet(\\n address indexed devAddress\\n );\\n\\n /// @notice Emitted if Relay Server is inactive for an `abandonmentDelay` and contract owner initiates its removal.\\n event RelayServerAbandoned(\\n address indexed relayManager,\\n uint256 abandonedTime\\n );\\n\\n /// @notice Emitted to indicate an action performed by a relay server to prevent it from being marked as abandoned.\\n event RelayServerKeepalive(\\n address indexed relayManager,\\n uint256 keepaliveTime\\n );\\n\\n /// @notice Emitted when the stake of an abandoned relayer has been confiscated and transferred to the `devAddress`.\\n event AbandonedRelayManagerStakeEscheated(\\n address indexed relayManager,\\n address indexed owner,\\n IERC20 token,\\n uint256 amount\\n );\\n\\n /**\\n * @param stake - amount of ether staked for this relay\\n * @param unstakeDelay - number of seconds to elapse before the owner can retrieve the stake after calling 'unlock'\\n * @param withdrawTime - timestamp in seconds when 'withdraw' will be callable, or zero if the unlock has not been called\\n * @param owner - address that receives revenue and manages relayManager's stake\\n */\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelay;\\n uint256 withdrawTime;\\n uint256 abandonedTime;\\n uint256 keepaliveTime;\\n IERC20 token;\\n address owner;\\n }\\n\\n struct RelayHubInfo {\\n uint256 removalTime;\\n }\\n\\n /**\\n * @param devAddress - the address that will receive the 'abandoned' stake\\n * @param abandonmentDelay - the amount of time after which the relay can be marked as 'abandoned'\\n * @param escheatmentDelay - the amount of time after which the abandoned relay's stake and balance may be withdrawn to the `devAddress`\\n */\\n struct AbandonedRelayServerConfig {\\n address devAddress;\\n uint256 abandonmentDelay;\\n uint256 escheatmentDelay;\\n }\\n\\n /**\\n * @notice Set the owner of a Relay Manager. Called only by the RelayManager itself.\\n * Note that owners cannot transfer ownership - if the entry already exists, reverts.\\n * @param owner - owner of the relay (as configured off-chain)\\n */\\n function setRelayManagerOwner(address owner) external;\\n\\n /**\\n * @notice Put a stake for a relayManager and set its unstake delay.\\n * Only the owner can call this function. If the entry does not exist, reverts.\\n * The owner must give allowance of the ERC-20 token to the StakeManager before calling this method.\\n * It is the RelayHub who has a configurable list of minimum stakes per token. StakeManager accepts all tokens.\\n * @param token The address of an ERC-20 token that is used by the relayManager as a stake\\n * @param relayManager The address that represents a stake entry and controls relay registrations on relay hubs\\n * @param unstakeDelay The number of seconds to elapse before an owner can retrieve the stake after calling `unlock`\\n * @param amount The amount of tokens to be taken from the relayOwner and locked in the StakeManager as a stake\\n */\\n function stakeForRelayManager(IERC20 token, address relayManager, uint256 unstakeDelay, uint256 amount) external;\\n\\n /**\\n * @notice Schedule the unlocking of the stake. The `unstakeDelay` must pass before owner can call `withdrawStake`.\\n * @param relayManager The address of a Relay Manager whose stake is to be unlocked.\\n */\\n function unlockStake(address relayManager) external;\\n /**\\n * @notice Withdraw the unlocked stake.\\n * @param relayManager The address of a Relay Manager whose stake is to be withdrawn.\\n */\\n function withdrawStake(address relayManager) external;\\n\\n /**\\n * @notice Add the `RelayHub` to a list of authorized by this Relay Manager.\\n * This allows the RelayHub to penalize this Relay Manager. The `RelayHub` cannot trust a Relay it cannot penalize.\\n * @param relayManager The address of a Relay Manager whose stake is to be authorized for the new `RelayHub`.\\n * @param relayHub The address of a `RelayHub` to be authorized.\\n */\\n function authorizeHubByOwner(address relayManager, address relayHub) external;\\n\\n /**\\n * @notice Same as `authorizeHubByOwner` but can be called by the RelayManager itself.\\n */\\n function authorizeHubByManager(address relayHub) external;\\n\\n /**\\n * @notice Remove the `RelayHub` from a list of authorized by this Relay Manager.\\n * @param relayManager The address of a Relay Manager.\\n * @param relayHub The address of a `RelayHub` to be unauthorized.\\n */\\n function unauthorizeHubByOwner(address relayManager, address relayHub) external;\\n\\n /**\\n * @notice Same as `unauthorizeHubByOwner` but can be called by the RelayManager itself.\\n */\\n function unauthorizeHubByManager(address relayHub) external;\\n\\n /**\\n * Slash the stake of the relay relayManager. In order to prevent stake kidnapping, burns part of stake on the way.\\n * @param relayManager The address of a Relay Manager to be penalized.\\n * @param beneficiary The address that receives part of the penalty amount.\\n * @param amount A total amount of penalty to be withdrawn from stake.\\n */\\n function penalizeRelayManager(address relayManager, address beneficiary, uint256 amount) external;\\n\\n /**\\n * @notice Allows the contract owner to set the given `relayManager` as abandoned after a configurable delay.\\n * Its entire stake and balance will be taken from a relay if it does not respond to being marked as abandoned.\\n */\\n function markRelayAbandoned(address relayManager) external;\\n\\n /**\\n * @notice If more than `abandonmentDelay` has passed since the last Keepalive transaction, and relay manager\\n * has been marked as abandoned, and after that more that `escheatmentDelay` have passed, entire stake and\\n * balance will be taken from this relay.\\n */\\n function escheatAbandonedRelayStake(address relayManager) external;\\n\\n /**\\n * @notice Sets a new `keepaliveTime` for the given `relayManager`, preventing it from being marked as abandoned.\\n * Can be called by an authorized `RelayHub` or by the `relayOwner` address.\\n */\\n function updateRelayKeepaliveTime(address relayManager) external;\\n\\n /**\\n * @notice Check if the Relay Manager can be considered abandoned or not.\\n * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\\n */\\n function isRelayEscheatable(address relayManager) external view returns(bool);\\n\\n /**\\n * @notice Get the stake details information for the given Relay Manager.\\n * @param relayManager The address of a Relay Manager.\\n * @return stakeInfo The `StakeInfo` structure.\\n * @return isSenderAuthorizedHub `true` if the `msg.sender` for this call was a `RelayHub` that is authorized now.\\n * `false` if the `msg.sender` for this call is not authorized.\\n */\\n function getStakeInfo(address relayManager) external view returns (StakeInfo memory stakeInfo, bool isSenderAuthorizedHub);\\n\\n /**\\n * @return The maximum unstake delay this `StakeManger` allows. This is to prevent locking money forever by mistake.\\n */\\n function getMaxUnstakeDelay() external view returns (uint256);\\n\\n /**\\n * @notice Change the address that will receive the 'burned' part of the penalized stake.\\n * This is done to prevent malicious Relay Server from penalizing itself and breaking even.\\n */\\n function setBurnAddress(address _burnAddress) external;\\n\\n /**\\n * @return The address that will receive the 'burned' part of the penalized stake.\\n */\\n function getBurnAddress() external view returns (address);\\n\\n /**\\n * @notice Change the address that will receive the 'abandoned' stake.\\n * This is done to prevent Relay Servers that lost their keys from losing access to funds.\\n */\\n function setDevAddress(address _burnAddress) external;\\n\\n /**\\n * @return The structure that contains all configuration values for the 'abandoned' stake.\\n */\\n function getAbandonedRelayServerConfig() external view returns (AbandonedRelayServerConfig memory);\\n\\n /**\\n * @return the block number in which the contract has been deployed.\\n */\\n function getCreationBlock() external view returns (uint256);\\n\\n /**\\n * @return a SemVer-compliant version of the `StakeManager` contract.\\n */\\n function versionSM() external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x77035b55ca4c09cb499bc0cab3f9e791d77597b148dbfee8bf94ca6c0039c3e0\",\"license\":\"GPL-3.0-only\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../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 * By default, the owner account will be the one that deploys the contract. This\\n * can 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 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\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 require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\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 require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\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\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x610120604052602f60c0818152906200214860e03980516200002a9160019160209091019062000246565b503480156200003857600080fd5b5060405162002177380380620021778339810160408190526200005b9162000309565b6200006633620000f0565b6001600160a01b038216620000c25760405162461bcd60e51b815260206004820181905260248201527f7472616e736665727320746f2061646472657373283029206d6179206661696c60448201526064015b60405180910390fd5b620000cd8262000140565b620000d88162000194565b50504360a0526080929092526003556004556200039b565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6200014a620001e8565b600580546001600160a01b0319166001600160a01b0383169081179091556040517fb0d2ad16ddd4d3dd008ebff0b7e7699bbfa920003cb0764acb871951d1cd499990600090a250565b6200019e620001e8565b600280546001600160a01b0319166001600160a01b0383169081179091556040517f78ef0ef64366f55e36ce7c04060e8bc5846d3651c53909eafc38458922d8a87990600090a250565b6000546001600160a01b03163314620002445760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000b9565b565b82805462000254906200035e565b90600052602060002090601f016020900481019282620002785760008555620002c3565b82601f106200029357805160ff1916838001178555620002c3565b82800160010185558215620002c3579182015b82811115620002c3578251825591602001919060010190620002a6565b50620002d1929150620002d5565b5090565b5b80821115620002d15760008155600101620002d6565b80516001600160a01b03811681146200030457600080fd5b919050565b600080600080600060a086880312156200032257600080fd5b8551945060208601519350604086015192506200034260608701620002ec565b91506200035260808701620002ec565b90509295509295909350565b600181811c908216806200037357607f821691505b602082108114156200039557634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a051611d80620003c860003960006102990152600081816103cc015261083a0152611d806000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c80637835d296116100f9578063c5f0674311610097578063f2fde38b11610071578063f2fde38b146104d6578063f48f8ac7146104e9578063f9bce311146104fc578063fece3dd41461050f57600080fd5b8063c5f067431461047d578063d0d41fe1146104b0578063d48a9d43146104c357600080fd5b8063a9aadcd7116100d3578063a9aadcd7146103b7578063afcb7752146103ca578063c23a5cea146103f0578063c34531531461040357600080fd5b80637835d296146103685780637aeb642a1461037b5780638da5cb5b146103a657600080fd5b806339622167116101665780634a1ce599116101405780634a1ce599146103275780634b0e72161461033a578063715018a61461034d57806371fa1faf1461035557600080fd5b806339622167146102ec57806346dcbf0b146102ff57806347116c6e1461031257600080fd5b806301ffc9a7146101ae57806309a08af4146101d657806314080fac146101eb57806316934fc4146101fe57806320ffd56d1461029757806338b39d29146102c7575b600080fd5b6101c16101bc366004611b85565b610522565b60405190151581526020015b60405180910390f35b6101e96101e4366004611b22565b610558565b005b6101e96101f9366004611baf565b61078c565b61025661020c366004611acc565b600660208190526000918252604090912080546001820154600283015460038401546004850154600586015495909601549395929491939092916001600160a01b03908116911687565b60408051978852602088019690965294860193909352606085019190915260808401526001600160a01b0390811660a08401521660c082015260e0016101cd565b7f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020016101cd565b6005546001600160a01b03165b6040516001600160a01b0390911681526020016101cd565b6101c16102fa366004611acc565b610a58565b6101e961030d366004611acc565b610aed565b61031a610bd2565b6040516101cd9190611c11565b6101e9610335366004611acc565b610c60565b6101e9610348366004611acc565b610d59565b6101e9610dab565b6101e9610363366004611acc565b610dbf565b6101e9610376366004611ae9565b610f29565b6102b9610389366004611ae9565b600760209081526000928352604080842090915290825290205481565b6000546001600160a01b03166102d4565b6101e96103c5366004611acc565b610f7a565b7f00000000000000000000000000000000000000000000000000000000000000006102b9565b6101e96103fe366004611acc565b61106f565b610416610411366004611acc565b6111de565b6040805183518152602080850151908201528382015191810191909152606080840151908201526080808401519082015260a0808401516001600160a01b039081169183019190915260c0938401511692810192909252151560e0820152610100016101cd565b6104856112bd565b6040805182516001600160a01b031681526020808401519082015291810151908201526060016101cd565b6101e96104be366004611acc565b611318565b6101e96104d1366004611acc565b61136a565b6101e96104e4366004611acc565b6113d1565b6101e96104f7366004611ae9565b61144a565b6101e961050a366004611acc565b611495565b6101e961051d366004611acc565b6114f8565b60006001600160e01b0319821662db127760e01b148061055257506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001600160a01b0383166000908152600760209081526040808320338452909152902054806105c35760405162461bcd60e51b81526020600482015260126024820152711a1d58881b9bdd08185d5d1a1bdc9a5e995960721b60448201526064015b60405180910390fd5b4281116106125760405162461bcd60e51b815260206004820152601960248201527f68756220617574686f72697a6174696f6e20657870697265640000000000000060448201526064016105ba565b6001600160a01b0384166000908152600660205260409020548211156106725760405162461bcd60e51b815260206004820152601560248201527470656e616c74792065786365656473207374616b6560581b60448201526064016105ba565b6001600160a01b038416600090815260066020526040902054610696908390611ca1565b6001600160a01b0385166000908152600660205260408120919091556106bd600284611c7f565b905060006106cb8285611ca1565b600580546001600160a01b038981166000908152600660205260409020909201549293506106fd9282169116846115f4565b6001600160a01b03808716600090815260066020526040902060050154610726911686836115f4565b6001600160a01b038681166000818152600660209081526040918290206005015482519085168152908101859052928816927f2da6b6c9084d39eeb104d765e33a4e16c8762e01b37383b75202d17515d1b82b91015b60405180910390a3505050505050565b6001600160a01b0380841660009081526006602081905260409091209081015485921633146107cd5760405162461bcd60e51b81526004016105ba90611c44565b6001600160a01b0385166000908152600660205260409020600101548410156108385760405162461bcd60e51b815260206004820181905260248201527f756e7374616b6544656c61792063616e6e6f742062652064656372656173656460448201526064016105ba565b7f000000000000000000000000000000000000000000000000000000000000000084111561089f5760405162461bcd60e51b8152602060048201526014602482015273756e7374616b6544656c617920746f6f2062696760601b60448201526064016105ba565b6001600160a01b0386166108f55760405162461bcd60e51b815260206004820181905260248201527f6d7573742073706563696679207374616b6520746f6b656e206164647265737360448201526064016105ba565b6001600160a01b0385811660009081526006602052604090206005015416158061093e57506001600160a01b038581166000908152600660205260409020600501548116908716145b61098a5760405162461bcd60e51b815260206004820181905260248201527f7374616b6520746f6b656e206164647265737320697320696e636f727265637460448201526064016105ba565b61099f6001600160a01b03871633308661165c565b6001600160a01b0385811660009081526006602052604081206005810180546001600160a01b031916938a16939093179092558154859291906109e3908490611c67565b90915550506001600160a01b03858116600081815260066020818152604092839020600181018a9055918201546005830154925484519387168452918301919091529181018890529216917ff83af4359c42f5104d95351ec3dd5e88f5344bc7eaea8de052c9b0d5254808fc9060600161077c565b6001600160a01b038082166000908152600660208181526040808420815160e08101835281548152600182015493810193909352600281015491830191909152600381015460608301819052600482015460808401526005820154861660a084015292015490931660c084015290919015801590610ae6575060045460608201514291610ae491611c67565b105b9392505050565b6001600160a01b0381811660009081526006602081815260408084206007835281852033808752935293205491830154929360001990921492909116148180610b335750805b610b7f5760405162461bcd60e51b815260206004820152601e60248201527f6d7573742062652063616c6c6564206279206f776e6572206f7220687562000060448201526064016105ba565b6000600384015542600484018190556040519081526001600160a01b038516907f27f31d9acb21058a327d122842d8dfa9641e7b6600ff715e99b9164080109e099060200160405180910390a250505050565b60018054610bdf90611ce4565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0b90611ce4565b8015610c585780601f10610c2d57610100808354040283529160200191610c58565b820191906000526020600020905b815481529060010190602001808311610c3b57829003601f168201915b505050505081565b6001600160a01b038082166000908152600660208190526040909120908101548392163314610ca15760405162461bcd60e51b81526004016105ba90611c44565b6001600160a01b0383166000908152600660205260409020600281015415610cfd5760405162461bcd60e51b815260206004820152600f60248201526e616c72656164792070656e64696e6760881b60448201526064016105ba565b6001810154610d0c9042611c67565b6002820181905560405190815233906001600160a01b038616907f9ffc6168de1eb7f1d16200f614753cd7edce5a2186aab1c612199dd7316cd7c49060200160405180910390a350505050565b610d61611694565b600580546001600160a01b0319166001600160a01b0383169081179091556040517fb0d2ad16ddd4d3dd008ebff0b7e7699bbfa920003cb0764acb871951d1cd499990600090a250565b610db3611694565b610dbd60006116ee565b565b610dc7611694565b6001600160a01b03811660009081526006602052604090208054610e2d5760405162461bcd60e51b815260206004820152601860248201527f72656c6179206d616e61676572206e6f74207374616b6564000000000000000060448201526064016105ba565b600381015415610e7f5760405162461bcd60e51b815260206004820152601f60248201527f72656c6179206d616e6167657220616c7265616479206162616e646f6e65640060448201526064016105ba565b60035460048201544291610e9291611c67565b10610edf5760405162461bcd60e51b815260206004820181905260248201527f72656c6179206d616e616765722077617320616c69766520726563656e746c7960448201526064016105ba565b42600382018190556040519081526001600160a01b038316907f2931c4798cd84eb47ddd8e2b225e48c52a4cdbbdb49fc6e259dc16ac359d9bcf9060200160405180910390a25050565b6001600160a01b038083166000908152600660208190526040909120908101548492163314610f6a5760405162461bcd60e51b81526004016105ba90611c44565b610f74848461173e565b50505050565b610f82611694565b6001600160a01b0381166000908152600660205260409020610fa382610a58565b610fef5760405162461bcd60e51b815260206004820181905260248201527f72656c617920736572766572206e6f74206573636865617461626c652079657460448201526064016105ba565b8054600080835560028084019190915554600583015461101c916001600160a01b039182169116836115f4565b6005820154604080516001600160a01b0392831681526020810184905233928616917f0c82251845a9397018c808e8698b438fbce74fbdbdd67b554861e0ce38d1ff0e91015b60405180910390a3505050565b6001600160a01b0380821660009081526006602081905260409091209081015483921633146110b05760405162461bcd60e51b81526004016105ba90611c44565b6001600160a01b038316600090815260066020526040902060028101546111195760405162461bcd60e51b815260206004820152601b60248201527f5769746864726177616c206973206e6f74207363686564756c6564000000000060448201526064016105ba565b42816002015411156111655760405162461bcd60e51b81526020600482015260156024820152745769746864726177616c206973206e6f742064756560581b60448201526064016105ba565b805460008083556002830155600582015461118a906001600160a01b031633836115f4565b6005820154604080516001600160a01b0392831681526020810184905233928816917fddbbe0a4d722dc62b8a415c5e38b88260d0e7a4848cacc83f41fbee40f700168910160405180910390a35050505050565b6112306040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681525090565b506001600160a01b039081166000818152600760209081526040808320338452825280832054938352600680835292819020815160e0810183528154815260018201549381019390935260028101549183019190915260038101546060830152600481015460808301526005810154851660a08301529091015490921660c0830152909160001990911490565b6112ea604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b50604080516060810182526002546001600160a01b0316815260035460208201526004549181019190915290565b611320611694565b600280546001600160a01b0319166001600160a01b0383169081179091556040517f78ef0ef64366f55e36ce7c04060e8bc5846d3651c53909eafc38458922d8a87990600090a250565b336000908152600660208190526040909120908101546001600160a01b03166113c35760405162461bcd60e51b815260206004820152600b60248201526a3737ba1036b0b730b3b2b960a91b60448201526064016105ba565b6113cd338361173e565b5050565b6113d9611694565b6001600160a01b03811661143e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105ba565b611447816116ee565b50565b6001600160a01b03808316600090815260066020819052604090912090810154849216331461148b5760405162461bcd60e51b81526004016105ba90611c44565b610f748484611795565b336000908152600660208190526040909120908101546001600160a01b03166114ee5760405162461bcd60e51b815260206004820152600b60248201526a3737ba1036b0b730b3b2b960a91b60448201526064016105ba565b6113cd3383611795565b6001600160a01b03811661153e5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b21037bbb732b960991b60448201526064016105ba565b33600090815260066020819052604090912001546001600160a01b0316156115985760405162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481bdddb9959609a1b60448201526064016105ba565b33600081815260066020819052604080832090910180546001600160a01b0319166001600160a01b03861690811790915590519092917f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73591a350565b6040516001600160a01b03831660248201526044810182905261165790849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261186a565b505050565b6040516001600160a01b0380851660248301528316604482015260648101829052610f749085906323b872dd60e01b90608401611620565b6000546001600160a01b03163314610dbd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105ba565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038083166000818152600760209081526040808320948616808452949091528082206000199055517fe292c4f6e9f34c975f4958cd5650a8111352feae914a67b064079571054210219190a35050565b6001600160a01b0380831660009081526007602090815260408083209385168352929052208054600019146118015760405162461bcd60e51b81526020600482015260126024820152711a1d58881b9bdd08185d5d1a1bdc9a5e995960721b60448201526064016105ba565b6001600160a01b0383166000908152600660205260409020600101546118279042611c67565b8082556040519081526001600160a01b0383811691908516907f8d941c9b73ba7e59671a59eed85054004624684182b0e4bdb56c35937bac65a690602001611062565b60006118bf826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661193f9092919063ffffffff16565b90508051600014806118e05750808060200190518101906118e09190611b63565b6116575760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105ba565b606061194e8484600085611956565b949350505050565b6060824710156119b75760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016105ba565b600080866001600160a01b031685876040516119d39190611bf5565b60006040518083038185875af1925050503d8060008114611a10576040519150601f19603f3d011682016040523d82523d6000602084013e611a15565b606091505b5091509150611a2687838387611a31565b979650505050505050565b60608315611a9d578251611a96576001600160a01b0385163b611a965760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105ba565b508161194e565b61194e8383815115611ab25781518083602001fd5b8060405162461bcd60e51b81526004016105ba9190611c11565b600060208284031215611ade57600080fd5b8135610ae681611d35565b60008060408385031215611afc57600080fd5b8235611b0781611d35565b91506020830135611b1781611d35565b809150509250929050565b600080600060608486031215611b3757600080fd5b8335611b4281611d35565b92506020840135611b5281611d35565b929592945050506040919091013590565b600060208284031215611b7557600080fd5b81518015158114610ae657600080fd5b600060208284031215611b9757600080fd5b81356001600160e01b031981168114610ae657600080fd5b60008060008060808587031215611bc557600080fd5b8435611bd081611d35565b93506020850135611be081611d35565b93969395505050506040820135916060013590565b60008251611c07818460208701611cb8565b9190910192915050565b6020815260008251806020840152611c30816040850160208701611cb8565b601f01601f19169190910160400192915050565b6020808252600990820152683737ba1037bbb732b960b91b604082015260600190565b60008219821115611c7a57611c7a611d1f565b500190565b600082611c9c57634e487b7160e01b600052601260045260246000fd5b500490565b600082821015611cb357611cb3611d1f565b500390565b60005b83811015611cd3578181015183820152602001611cbb565b83811115610f745750506000910152565b600181811c90821680611cf857607f821691505b60208210811415611d1957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811461144757600080fdfea26469706673582212204a6451a93a4c6021bcd23cb93b30d6c5de983f67f60560b3b79e671f50fc009a64736f6c63430008070033332e302e302d626574612e332b6f70656e67736e2e7374616b656d616e616765722e697374616b656d616e61676572", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c80637835d296116100f9578063c5f0674311610097578063f2fde38b11610071578063f2fde38b146104d6578063f48f8ac7146104e9578063f9bce311146104fc578063fece3dd41461050f57600080fd5b8063c5f067431461047d578063d0d41fe1146104b0578063d48a9d43146104c357600080fd5b8063a9aadcd7116100d3578063a9aadcd7146103b7578063afcb7752146103ca578063c23a5cea146103f0578063c34531531461040357600080fd5b80637835d296146103685780637aeb642a1461037b5780638da5cb5b146103a657600080fd5b806339622167116101665780634a1ce599116101405780634a1ce599146103275780634b0e72161461033a578063715018a61461034d57806371fa1faf1461035557600080fd5b806339622167146102ec57806346dcbf0b146102ff57806347116c6e1461031257600080fd5b806301ffc9a7146101ae57806309a08af4146101d657806314080fac146101eb57806316934fc4146101fe57806320ffd56d1461029757806338b39d29146102c7575b600080fd5b6101c16101bc366004611b85565b610522565b60405190151581526020015b60405180910390f35b6101e96101e4366004611b22565b610558565b005b6101e96101f9366004611baf565b61078c565b61025661020c366004611acc565b600660208190526000918252604090912080546001820154600283015460038401546004850154600586015495909601549395929491939092916001600160a01b03908116911687565b60408051978852602088019690965294860193909352606085019190915260808401526001600160a01b0390811660a08401521660c082015260e0016101cd565b7f00000000000000000000000000000000000000000000000000000000000000005b6040519081526020016101cd565b6005546001600160a01b03165b6040516001600160a01b0390911681526020016101cd565b6101c16102fa366004611acc565b610a58565b6101e961030d366004611acc565b610aed565b61031a610bd2565b6040516101cd9190611c11565b6101e9610335366004611acc565b610c60565b6101e9610348366004611acc565b610d59565b6101e9610dab565b6101e9610363366004611acc565b610dbf565b6101e9610376366004611ae9565b610f29565b6102b9610389366004611ae9565b600760209081526000928352604080842090915290825290205481565b6000546001600160a01b03166102d4565b6101e96103c5366004611acc565b610f7a565b7f00000000000000000000000000000000000000000000000000000000000000006102b9565b6101e96103fe366004611acc565b61106f565b610416610411366004611acc565b6111de565b6040805183518152602080850151908201528382015191810191909152606080840151908201526080808401519082015260a0808401516001600160a01b039081169183019190915260c0938401511692810192909252151560e0820152610100016101cd565b6104856112bd565b6040805182516001600160a01b031681526020808401519082015291810151908201526060016101cd565b6101e96104be366004611acc565b611318565b6101e96104d1366004611acc565b61136a565b6101e96104e4366004611acc565b6113d1565b6101e96104f7366004611ae9565b61144a565b6101e961050a366004611acc565b611495565b6101e961051d366004611acc565b6114f8565b60006001600160e01b0319821662db127760e01b148061055257506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001600160a01b0383166000908152600760209081526040808320338452909152902054806105c35760405162461bcd60e51b81526020600482015260126024820152711a1d58881b9bdd08185d5d1a1bdc9a5e995960721b60448201526064015b60405180910390fd5b4281116106125760405162461bcd60e51b815260206004820152601960248201527f68756220617574686f72697a6174696f6e20657870697265640000000000000060448201526064016105ba565b6001600160a01b0384166000908152600660205260409020548211156106725760405162461bcd60e51b815260206004820152601560248201527470656e616c74792065786365656473207374616b6560581b60448201526064016105ba565b6001600160a01b038416600090815260066020526040902054610696908390611ca1565b6001600160a01b0385166000908152600660205260408120919091556106bd600284611c7f565b905060006106cb8285611ca1565b600580546001600160a01b038981166000908152600660205260409020909201549293506106fd9282169116846115f4565b6001600160a01b03808716600090815260066020526040902060050154610726911686836115f4565b6001600160a01b038681166000818152600660209081526040918290206005015482519085168152908101859052928816927f2da6b6c9084d39eeb104d765e33a4e16c8762e01b37383b75202d17515d1b82b91015b60405180910390a3505050505050565b6001600160a01b0380841660009081526006602081905260409091209081015485921633146107cd5760405162461bcd60e51b81526004016105ba90611c44565b6001600160a01b0385166000908152600660205260409020600101548410156108385760405162461bcd60e51b815260206004820181905260248201527f756e7374616b6544656c61792063616e6e6f742062652064656372656173656460448201526064016105ba565b7f000000000000000000000000000000000000000000000000000000000000000084111561089f5760405162461bcd60e51b8152602060048201526014602482015273756e7374616b6544656c617920746f6f2062696760601b60448201526064016105ba565b6001600160a01b0386166108f55760405162461bcd60e51b815260206004820181905260248201527f6d7573742073706563696679207374616b6520746f6b656e206164647265737360448201526064016105ba565b6001600160a01b0385811660009081526006602052604090206005015416158061093e57506001600160a01b038581166000908152600660205260409020600501548116908716145b61098a5760405162461bcd60e51b815260206004820181905260248201527f7374616b6520746f6b656e206164647265737320697320696e636f727265637460448201526064016105ba565b61099f6001600160a01b03871633308661165c565b6001600160a01b0385811660009081526006602052604081206005810180546001600160a01b031916938a16939093179092558154859291906109e3908490611c67565b90915550506001600160a01b03858116600081815260066020818152604092839020600181018a9055918201546005830154925484519387168452918301919091529181018890529216917ff83af4359c42f5104d95351ec3dd5e88f5344bc7eaea8de052c9b0d5254808fc9060600161077c565b6001600160a01b038082166000908152600660208181526040808420815160e08101835281548152600182015493810193909352600281015491830191909152600381015460608301819052600482015460808401526005820154861660a084015292015490931660c084015290919015801590610ae6575060045460608201514291610ae491611c67565b105b9392505050565b6001600160a01b0381811660009081526006602081815260408084206007835281852033808752935293205491830154929360001990921492909116148180610b335750805b610b7f5760405162461bcd60e51b815260206004820152601e60248201527f6d7573742062652063616c6c6564206279206f776e6572206f7220687562000060448201526064016105ba565b6000600384015542600484018190556040519081526001600160a01b038516907f27f31d9acb21058a327d122842d8dfa9641e7b6600ff715e99b9164080109e099060200160405180910390a250505050565b60018054610bdf90611ce4565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0b90611ce4565b8015610c585780601f10610c2d57610100808354040283529160200191610c58565b820191906000526020600020905b815481529060010190602001808311610c3b57829003601f168201915b505050505081565b6001600160a01b038082166000908152600660208190526040909120908101548392163314610ca15760405162461bcd60e51b81526004016105ba90611c44565b6001600160a01b0383166000908152600660205260409020600281015415610cfd5760405162461bcd60e51b815260206004820152600f60248201526e616c72656164792070656e64696e6760881b60448201526064016105ba565b6001810154610d0c9042611c67565b6002820181905560405190815233906001600160a01b038616907f9ffc6168de1eb7f1d16200f614753cd7edce5a2186aab1c612199dd7316cd7c49060200160405180910390a350505050565b610d61611694565b600580546001600160a01b0319166001600160a01b0383169081179091556040517fb0d2ad16ddd4d3dd008ebff0b7e7699bbfa920003cb0764acb871951d1cd499990600090a250565b610db3611694565b610dbd60006116ee565b565b610dc7611694565b6001600160a01b03811660009081526006602052604090208054610e2d5760405162461bcd60e51b815260206004820152601860248201527f72656c6179206d616e61676572206e6f74207374616b6564000000000000000060448201526064016105ba565b600381015415610e7f5760405162461bcd60e51b815260206004820152601f60248201527f72656c6179206d616e6167657220616c7265616479206162616e646f6e65640060448201526064016105ba565b60035460048201544291610e9291611c67565b10610edf5760405162461bcd60e51b815260206004820181905260248201527f72656c6179206d616e616765722077617320616c69766520726563656e746c7960448201526064016105ba565b42600382018190556040519081526001600160a01b038316907f2931c4798cd84eb47ddd8e2b225e48c52a4cdbbdb49fc6e259dc16ac359d9bcf9060200160405180910390a25050565b6001600160a01b038083166000908152600660208190526040909120908101548492163314610f6a5760405162461bcd60e51b81526004016105ba90611c44565b610f74848461173e565b50505050565b610f82611694565b6001600160a01b0381166000908152600660205260409020610fa382610a58565b610fef5760405162461bcd60e51b815260206004820181905260248201527f72656c617920736572766572206e6f74206573636865617461626c652079657460448201526064016105ba565b8054600080835560028084019190915554600583015461101c916001600160a01b039182169116836115f4565b6005820154604080516001600160a01b0392831681526020810184905233928616917f0c82251845a9397018c808e8698b438fbce74fbdbdd67b554861e0ce38d1ff0e91015b60405180910390a3505050565b6001600160a01b0380821660009081526006602081905260409091209081015483921633146110b05760405162461bcd60e51b81526004016105ba90611c44565b6001600160a01b038316600090815260066020526040902060028101546111195760405162461bcd60e51b815260206004820152601b60248201527f5769746864726177616c206973206e6f74207363686564756c6564000000000060448201526064016105ba565b42816002015411156111655760405162461bcd60e51b81526020600482015260156024820152745769746864726177616c206973206e6f742064756560581b60448201526064016105ba565b805460008083556002830155600582015461118a906001600160a01b031633836115f4565b6005820154604080516001600160a01b0392831681526020810184905233928816917fddbbe0a4d722dc62b8a415c5e38b88260d0e7a4848cacc83f41fbee40f700168910160405180910390a35050505050565b6112306040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681525090565b506001600160a01b039081166000818152600760209081526040808320338452825280832054938352600680835292819020815160e0810183528154815260018201549381019390935260028101549183019190915260038101546060830152600481015460808301526005810154851660a08301529091015490921660c0830152909160001990911490565b6112ea604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b50604080516060810182526002546001600160a01b0316815260035460208201526004549181019190915290565b611320611694565b600280546001600160a01b0319166001600160a01b0383169081179091556040517f78ef0ef64366f55e36ce7c04060e8bc5846d3651c53909eafc38458922d8a87990600090a250565b336000908152600660208190526040909120908101546001600160a01b03166113c35760405162461bcd60e51b815260206004820152600b60248201526a3737ba1036b0b730b3b2b960a91b60448201526064016105ba565b6113cd338361173e565b5050565b6113d9611694565b6001600160a01b03811661143e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105ba565b611447816116ee565b50565b6001600160a01b03808316600090815260066020819052604090912090810154849216331461148b5760405162461bcd60e51b81526004016105ba90611c44565b610f748484611795565b336000908152600660208190526040909120908101546001600160a01b03166114ee5760405162461bcd60e51b815260206004820152600b60248201526a3737ba1036b0b730b3b2b960a91b60448201526064016105ba565b6113cd3383611795565b6001600160a01b03811661153e5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b21037bbb732b960991b60448201526064016105ba565b33600090815260066020819052604090912001546001600160a01b0316156115985760405162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481bdddb9959609a1b60448201526064016105ba565b33600081815260066020819052604080832090910180546001600160a01b0319166001600160a01b03861690811790915590519092917f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73591a350565b6040516001600160a01b03831660248201526044810182905261165790849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261186a565b505050565b6040516001600160a01b0380851660248301528316604482015260648101829052610f749085906323b872dd60e01b90608401611620565b6000546001600160a01b03163314610dbd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105ba565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038083166000818152600760209081526040808320948616808452949091528082206000199055517fe292c4f6e9f34c975f4958cd5650a8111352feae914a67b064079571054210219190a35050565b6001600160a01b0380831660009081526007602090815260408083209385168352929052208054600019146118015760405162461bcd60e51b81526020600482015260126024820152711a1d58881b9bdd08185d5d1a1bdc9a5e995960721b60448201526064016105ba565b6001600160a01b0383166000908152600660205260409020600101546118279042611c67565b8082556040519081526001600160a01b0383811691908516907f8d941c9b73ba7e59671a59eed85054004624684182b0e4bdb56c35937bac65a690602001611062565b60006118bf826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661193f9092919063ffffffff16565b90508051600014806118e05750808060200190518101906118e09190611b63565b6116575760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105ba565b606061194e8484600085611956565b949350505050565b6060824710156119b75760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016105ba565b600080866001600160a01b031685876040516119d39190611bf5565b60006040518083038185875af1925050503d8060008114611a10576040519150601f19603f3d011682016040523d82523d6000602084013e611a15565b606091505b5091509150611a2687838387611a31565b979650505050505050565b60608315611a9d578251611a96576001600160a01b0385163b611a965760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105ba565b508161194e565b61194e8383815115611ab25781518083602001fd5b8060405162461bcd60e51b81526004016105ba9190611c11565b600060208284031215611ade57600080fd5b8135610ae681611d35565b60008060408385031215611afc57600080fd5b8235611b0781611d35565b91506020830135611b1781611d35565b809150509250929050565b600080600060608486031215611b3757600080fd5b8335611b4281611d35565b92506020840135611b5281611d35565b929592945050506040919091013590565b600060208284031215611b7557600080fd5b81518015158114610ae657600080fd5b600060208284031215611b9757600080fd5b81356001600160e01b031981168114610ae657600080fd5b60008060008060808587031215611bc557600080fd5b8435611bd081611d35565b93506020850135611be081611d35565b93969395505050506040820135916060013590565b60008251611c07818460208701611cb8565b9190910192915050565b6020815260008251806020840152611c30816040850160208701611cb8565b601f01601f19169190910160400192915050565b6020808252600990820152683737ba1037bbb732b960b91b604082015260600190565b60008219821115611c7a57611c7a611d1f565b500190565b600082611c9c57634e487b7160e01b600052601260045260246000fd5b500490565b600082821015611cb357611cb3611d1f565b500390565b60005b83811015611cd3578181015183820152602001611cbb565b83811115610f745750506000910152565b600181811c90821680611cf857607f821691505b60208210811415611d1957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811461144757600080fdfea26469706673582212204a6451a93a4c6021bcd23cb93b30d6c5de983f67f60560b3b79e671f50fc009a64736f6c63430008070033", + "devdoc": { + "kind": "dev", + "methods": { + "authorizeHubByOwner(address,address)": { + "params": { + "relayHub": "The address of a `RelayHub` to be authorized.", + "relayManager": "The address of a Relay Manager whose stake is to be authorized for the new `RelayHub`." + } + }, + "getAbandonedRelayServerConfig()": { + "returns": { + "_0": "The structure that contains all configuration values for the 'abandoned' stake." + } + }, + "getBurnAddress()": { + "returns": { + "_0": "The address that will receive the 'burned' part of the penalized stake." + } + }, + "getCreationBlock()": { + "returns": { + "_0": "the block number in which the contract has been deployed." + } + }, + "getMaxUnstakeDelay()": { + "returns": { + "_0": "The maximum unstake delay this `StakeManger` allows. This is to prevent locking money forever by mistake." + } + }, + "getStakeInfo(address)": { + "params": { + "relayManager": "The address of a Relay Manager." + }, + "returns": { + "isSenderAuthorizedHub": "`true` if the `msg.sender` for this call was a `RelayHub` that is authorized now. `false` if the `msg.sender` for this call is not authorized.", + "stakeInfo": "The `StakeInfo` structure." + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "penalizeRelayManager(address,address,uint256)": { + "params": { + "amount": "A total amount of penalty to be withdrawn from stake.", + "beneficiary": "The address that receives part of the penalty amount.", + "relayManager": "The address of a Relay Manager to be penalized." + } + }, + "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." + }, + "setRelayManagerOwner(address)": { + "params": { + "owner": "- owner of the relay (as configured off-chain)" + } + }, + "stakeForRelayManager(address,address,uint256,uint256)": { + "params": { + "amount": "The amount of tokens to be taken from the relayOwner and locked in the StakeManager as a stake", + "relayManager": "The address that represents a stake entry and controls relay registrations on relay hubs", + "token": "The address of an ERC-20 token that is used by the relayManager as a stake", + "unstakeDelay": "The number of seconds to elapse before an owner can retrieve the stake after calling `unlock`" + } + }, + "supportsInterface(bytes4)": { + "details": "Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + }, + "unauthorizeHubByOwner(address,address)": { + "params": { + "relayHub": "The address of a `RelayHub` to be unauthorized.", + "relayManager": "The address of a Relay Manager." + } + }, + "unlockStake(address)": { + "params": { + "relayManager": "The address of a Relay Manager whose stake is to be unlocked." + } + }, + "withdrawStake(address)": { + "params": { + "relayManager": "The address of a Relay Manager whose stake is to be withdrawn." + } + } + }, + "stateVariables": { + "versionSM": { + "return": "a SemVer-compliant version of the `StakeManager` contract.", + "returns": { + "_0": "a SemVer-compliant version of the `StakeManager` contract." + } + } + }, + "title": "The StakeManager implementation", + "version": 1 + }, + "userdoc": { + "events": { + "AbandonedRelayManagerStakeEscheated(address,address,address,uint256)": { + "notice": "Emitted when the stake of an abandoned relayer has been confiscated and transferred to the `devAddress`." + }, + "BurnAddressSet(address)": { + "notice": "Emitted when a `burnAddress` is changed." + }, + "DevAddressSet(address)": { + "notice": "Emitted when a `devAddress` is changed." + }, + "HubAuthorized(address,address)": { + "notice": "Emitted when a `relayManager` adds a new `RelayHub` to a list of authorized." + }, + "HubUnauthorized(address,address,uint256)": { + "notice": "Emitted when a `relayManager` removes a `RelayHub` from a list of authorized." + }, + "OwnerSet(address,address)": { + "notice": "Emitted when a `relayManager` sets its `owner`. This is necessary to prevent stake hijacking." + }, + "RelayServerAbandoned(address,uint256)": { + "notice": "Emitted if Relay Server is inactive for an `abandonmentDelay` and contract owner initiates its removal." + }, + "RelayServerKeepalive(address,uint256)": { + "notice": "Emitted to indicate an action performed by a relay server to prevent it from being marked as abandoned." + }, + "StakeAdded(address,address,address,uint256,uint256)": { + "notice": "Emitted when a `stake` or `unstakeDelay` are initialized or increased." + }, + "StakePenalized(address,address,address,uint256)": { + "notice": "Emitted when an authorized `RelayHub` penalizes a `relayManager`." + }, + "StakeUnlocked(address,address,uint256)": { + "notice": "Emitted once a stake is scheduled for withdrawal." + }, + "StakeWithdrawn(address,address,address,uint256)": { + "notice": "Emitted when owner withdraws `relayManager` funds." + } + }, + "kind": "user", + "methods": { + "authorizeHubByManager(address)": { + "notice": "Same as `authorizeHubByOwner` but can be called by the RelayManager itself." + }, + "authorizeHubByOwner(address,address)": { + "notice": "Add the `RelayHub` to a list of authorized by this Relay Manager. This allows the RelayHub to penalize this Relay Manager. The `RelayHub` cannot trust a Relay it cannot penalize." + }, + "authorizedHubs(address,address)": { + "notice": "maps relay managers to a map of addressed of their authorized hubs to the information on that hub" + }, + "escheatAbandonedRelayStake(address)": { + "notice": "If more than `abandonmentDelay` has passed since the last Keepalive transaction, and relay manager has been marked as abandoned, and after that more that `escheatmentDelay` have passed, entire stake and balance will be taken from this relay." + }, + "getStakeInfo(address)": { + "notice": "Get the stake details information for the given Relay Manager." + }, + "isRelayEscheatable(address)": { + "notice": "Check if the Relay Manager can be considered abandoned or not. Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise." + }, + "markRelayAbandoned(address)": { + "notice": "Allows the contract owner to set the given `relayManager` as abandoned after a configurable delay. Its entire stake and balance will be taken from a relay if it does not respond to being marked as abandoned." + }, + "penalizeRelayManager(address,address,uint256)": { + "notice": "Slash the stake of the relay relayManager. In order to prevent stake kidnapping, burns part of stake on the way." + }, + "setBurnAddress(address)": { + "notice": "Change the address that will receive the 'burned' part of the penalized stake. This is done to prevent malicious Relay Server from penalizing itself and breaking even." + }, + "setDevAddress(address)": { + "notice": "Change the address that will receive the 'abandoned' stake. This is done to prevent Relay Servers that lost their keys from losing access to funds." + }, + "setRelayManagerOwner(address)": { + "notice": "Set the owner of a Relay Manager. Called only by the RelayManager itself. Note that owners cannot transfer ownership - if the entry already exists, reverts." + }, + "stakeForRelayManager(address,address,uint256,uint256)": { + "notice": "Put a stake for a relayManager and set its unstake delay. Only the owner can call this function. If the entry does not exist, reverts. The owner must give allowance of the ERC-20 token to the StakeManager before calling this method. It is the RelayHub who has a configurable list of minimum stakes per token. StakeManager accepts all tokens." + }, + "stakes(address)": { + "notice": "maps relay managers to their stakes" + }, + "unauthorizeHubByManager(address)": { + "notice": "Same as `unauthorizeHubByOwner` but can be called by the RelayManager itself." + }, + "unauthorizeHubByOwner(address,address)": { + "notice": "Remove the `RelayHub` from a list of authorized by this Relay Manager." + }, + "unlockStake(address)": { + "notice": "Schedule the unlocking of the stake. The `unstakeDelay` must pass before owner can call `withdrawStake`." + }, + "updateRelayKeepaliveTime(address)": { + "notice": "Sets a new `keepaliveTime` for the given `relayManager`, preventing it from being marked as abandoned. Can be called by an authorized `RelayHub` or by the `relayOwner` address." + }, + "withdrawStake(address)": { + "notice": "Withdraw the unlocked stake." + } + }, + "notice": "An IStakeManager instance that accepts stakes in any ERC-20 token.Single StakeInfo of a single RelayManager can only have one token address assigned to it.It cannot be changed after the first time 'stakeForRelayManager' is called as it is equivalent to withdrawal.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 8589, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 3294, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "versionSM", + "offset": 0, + "slot": "1", + "type": "t_string_storage" + }, + { + "astId": 3299, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "abandonedRelayServerConfig", + "offset": 0, + "slot": "2", + "type": "t_struct(AbandonedRelayServerConfig)5744_storage" + }, + { + "astId": 3301, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "burnAddress", + "offset": 0, + "slot": "5", + "type": "t_address" + }, + { + "astId": 3309, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "stakes", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_struct(StakeInfo)5734_storage)" + }, + { + "astId": 3422, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "authorizedHubs", + "offset": 0, + "slot": "7", + "type": "t_mapping(t_address,t_mapping(t_address,t_struct(RelayHubInfo)5737_storage))" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_contract(IERC20)9362": { + "encoding": "inplace", + "label": "contract IERC20", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_struct(RelayHubInfo)5737_storage))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => struct IStakeManager.RelayHubInfo))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_struct(RelayHubInfo)5737_storage)" + }, + "t_mapping(t_address,t_struct(RelayHubInfo)5737_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct IStakeManager.RelayHubInfo)", + "numberOfBytes": "32", + "value": "t_struct(RelayHubInfo)5737_storage" + }, + "t_mapping(t_address,t_struct(StakeInfo)5734_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct IStakeManager.StakeInfo)", + "numberOfBytes": "32", + "value": "t_struct(StakeInfo)5734_storage" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(AbandonedRelayServerConfig)5744_storage": { + "encoding": "inplace", + "label": "struct IStakeManager.AbandonedRelayServerConfig", + "members": [ + { + "astId": 5739, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "devAddress", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 5741, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "abandonmentDelay", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 5743, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "escheatmentDelay", + "offset": 0, + "slot": "2", + "type": "t_uint256" + } + ], + "numberOfBytes": "96" + }, + "t_struct(RelayHubInfo)5737_storage": { + "encoding": "inplace", + "label": "struct IStakeManager.RelayHubInfo", + "members": [ + { + "astId": 5736, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "removalTime", + "offset": 0, + "slot": "0", + "type": "t_uint256" + } + ], + "numberOfBytes": "32" + }, + "t_struct(StakeInfo)5734_storage": { + "encoding": "inplace", + "label": "struct IStakeManager.StakeInfo", + "members": [ + { + "astId": 5720, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "stake", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 5722, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "unstakeDelay", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 5724, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "withdrawTime", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 5726, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "abandonedTime", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 5728, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "keepaliveTime", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 5731, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "token", + "offset": 0, + "slot": "5", + "type": "t_contract(IERC20)9362" + }, + { + "astId": 5733, + "contract": "@opengsn/contracts/src/StakeManager.sol:StakeManager", + "label": "owner", + "offset": 0, + "slot": "6", + "type": "t_address" + } + ], + "numberOfBytes": "224" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/gsn/deploy/data/deployments/amoy/TestWrappedNativeToken.json b/gsn/deploy/data/deployments/amoy/TestWrappedNativeToken.json new file mode 100644 index 00000000..6d80b8ac --- /dev/null +++ b/gsn/deploy/data/deployments/amoy/TestWrappedNativeToken.json @@ -0,0 +1,462 @@ +{ + "address": "0xBB509181d7332D20C84d8b9cCF243F3c0cF4346e", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x0836106dddac2947dcf005f139785147926f78756d7b78f2cf257171b43e17d9", + "receipt": { + "to": null, + "from": "0x61B1E290d2F465d6667336d4934941aa2517AfA2", + "contractAddress": "0xBB509181d7332D20C84d8b9cCF243F3c0cF4346e", + "transactionIndex": 1, + "gasUsed": "761793", + "logsBloom": "0x00000000000000000008000000000000000000000000000000000000000000000000000000000002000000000000000000008000000000000000010000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000004000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000008001000000000000000000000000000000100000000000000000000000000000000000010000000000000000000000000000000000100000", + "blockHash": "0x374dfb5052aa80fb264b2c1e35942113e169d16ed27b0b9048d808eac3a14788", + "transactionHash": "0x0836106dddac2947dcf005f139785147926f78756d7b78f2cf257171b43e17d9", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 4880189, + "transactionHash": "0x0836106dddac2947dcf005f139785147926f78756d7b78f2cf257171b43e17d9", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x00000000000000000000000061b1e290d2f465d6667336d4934941aa2517afa2", + "0x00000000000000000000000009207a6efee346cb3e4a54ac18523e3715d38b3f" + ], + "data": "0x00000000000000000000000000000000000000000000000000a262cd44c2fbb100000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000e3ba29a83f1a62674000000000000000000000000000000000000000000000000064df88c8eef044f00000000000000000000000000000000000000000000000e3c44fd5136692225", + "logIndex": 2, + "blockHash": "0x374dfb5052aa80fb264b2c1e35942113e169d16ed27b0b9048d808eac3a14788" + } + ], + "blockNumber": 4880189, + "cumulativeGasUsed": "782793", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "766eaa539015b343a6f8732a84d5a9ae", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"minimal \\\"wrapped eth\\\" implementation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts-link/test/TestWrappedNativeToken.sol\":\"TestWrappedNativeToken\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(address from, address to, uint256 amount) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n}\\n\",\"keccak256\":\"0xa56ca923f70c1748830700250b19c61b70db9a683516dc5e216694a50445d99c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts-link/interfaces/IERC20Token.sol\":{\"content\":\"pragma solidity >=0.7.6;\\n\\n// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\n/**\\n * @notice Extended ERC-20 token interface used internally in OpenGSN modules.\\n * Renamed to avoid conflict with OZ namespace. Includes IERC20, ERC20Metadata.\\n * added semi-standard \\\"wrapped eth\\\" access methods deposit() and \\\"withdraw()\\\"\\n */\\ninterface IERC20Token is IERC20, IERC20Metadata {\\n\\n function deposit() external payable;\\n function withdraw(uint256 amount) external;\\n}\",\"keccak256\":\"0xe949e04eabf3596f6e5943f4dda66c32fdef7704253ea15394429a07fc4dfb61\",\"license\":\"MIT\"},\"contracts-link/test/TestWrappedNativeToken.sol\":{\"content\":\"pragma solidity ^0.8.0;\\n\\n// SPDX-License-Identifier:MIT\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../interfaces/IERC20Token.sol\\\";\\n\\n/**\\n * @notice minimal \\\"wrapped eth\\\" implementation.\\n */\\ncontract TestWrappedNativeToken is ERC20, IERC20Token {\\n\\n // solhint-disable-next-line no-empty-blocks\\n constructor() ERC20(\\\"Wrapped Native Token\\\", \\\"wnTok\\\") {\\n }\\n\\n receive() external payable {\\n deposit();\\n }\\n\\n function deposit() public override payable {\\n _mint(msg.sender, msg.value);\\n }\\n\\n function withdraw(uint256 amount) public override {\\n _burn(msg.sender, amount);\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success,) = msg.sender.call{value:amount}(\\\"\\\");\\n require(success, \\\"transfer failed\\\");\\n }\\n}\",\"keccak256\":\"0x9a9e39d587738bac425ce64e58467c3a5b391bab34fd69ca709d72d8cb87e9b2\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50604080518082018252601481527f57726170706564204e617469766520546f6b656e000000000000000000000000602080830191825283518085019094526005845264776e546f6b60d81b908401528151919291620000749160039162000093565b5080516200008a90600490602084019062000093565b50505062000176565b828054620000a19062000139565b90600052602060002090601f016020900481019282620000c5576000855562000110565b82601f10620000e057805160ff191683800117855562000110565b8280016001018555821562000110579182015b8281111562000110578251825591602001919060010190620000f3565b506200011e92915062000122565b5090565b5b808211156200011e576000815560010162000123565b600181811c908216806200014e57607f821691505b602082108114156200017057634e487b7160e01b600052602260045260246000fd5b50919050565b610be780620001866000396000f3fe6080604052600436106100c65760003560e01c8063395093511161007f578063a457c2d711610059578063a457c2d71461021b578063a9059cbb1461023b578063d0e30db01461025b578063dd62ed3e1461026357600080fd5b806339509351146101b057806370a08231146101d057806395d89b411461020657600080fd5b806306fdde03146100da578063095ea7b31461010557806318160ddd1461013557806323b872dd146101545780632e1a7d4d14610174578063313ce5671461019457600080fd5b366100d5576100d3610283565b005b600080fd5b3480156100e657600080fd5b506100ef61028f565b6040516100fc9190610afb565b60405180910390f35b34801561011157600080fd5b50610125610120366004610ab8565b610321565b60405190151581526020016100fc565b34801561014157600080fd5b506002545b6040519081526020016100fc565b34801561016057600080fd5b5061012561016f366004610a7c565b610339565b34801561018057600080fd5b506100d361018f366004610ae2565b61035d565b3480156101a057600080fd5b50604051601281526020016100fc565b3480156101bc57600080fd5b506101256101cb366004610ab8565b6103fa565b3480156101dc57600080fd5b506101466101eb366004610a27565b6001600160a01b031660009081526020819052604090205490565b34801561021257600080fd5b506100ef61041c565b34801561022757600080fd5b50610125610236366004610ab8565b61042b565b34801561024757600080fd5b50610125610256366004610ab8565b6104a6565b6100d3610283565b34801561026f57600080fd5b5061014661027e366004610a49565b6104b4565b61028d33346104df565b565b60606003805461029e90610b76565b80601f01602080910402602001604051908101604052809291908181526020018280546102ca90610b76565b80156103175780601f106102ec57610100808354040283529160200191610317565b820191906000526020600020905b8154815290600101906020018083116102fa57829003601f168201915b5050505050905090565b60003361032f81858561059e565b5060019392505050565b6000336103478582856106c3565b61035285858561073d565b506001949350505050565b61036733826108e1565b604051600090339083908381818185875af1925050503d80600081146103a9576040519150601f19603f3d011682016040523d82523d6000602084013e6103ae565b606091505b50509050806103f65760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b60448201526064015b60405180910390fd5b5050565b60003361032f81858561040d83836104b4565b6104179190610b50565b61059e565b60606004805461029e90610b76565b6000338161043982866104b4565b9050838110156104995760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016103ed565b610352828686840361059e565b60003361032f81858561073d565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0382166105355760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103ed565b80600260008282546105479190610b50565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0383166106005760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016103ed565b6001600160a01b0382166106615760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016103ed565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006106cf84846104b4565b90506000198114610737578181101561072a5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103ed565b610737848484840361059e565b50505050565b6001600160a01b0383166107a15760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016103ed565b6001600160a01b0382166108035760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016103ed565b6001600160a01b0383166000908152602081905260409020548181101561087b5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016103ed565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610737565b6001600160a01b0382166109415760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016103ed565b6001600160a01b038216600090815260208190526040902054818110156109b55760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016103ed565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016106b6565b80356001600160a01b0381168114610a2257600080fd5b919050565b600060208284031215610a3957600080fd5b610a4282610a0b565b9392505050565b60008060408385031215610a5c57600080fd5b610a6583610a0b565b9150610a7360208401610a0b565b90509250929050565b600080600060608486031215610a9157600080fd5b610a9a84610a0b565b9250610aa860208501610a0b565b9150604084013590509250925092565b60008060408385031215610acb57600080fd5b610ad483610a0b565b946020939093013593505050565b600060208284031215610af457600080fd5b5035919050565b600060208083528351808285015260005b81811015610b2857858101830151858201604001528201610b0c565b81811115610b3a576000604083870101525b50601f01601f1916929092016040019392505050565b60008219821115610b7157634e487b7160e01b600052601160045260246000fd5b500190565b600181811c90821680610b8a57607f821691505b60208210811415610bab57634e487b7160e01b600052602260045260246000fd5b5091905056fea26469706673582212207934469329607db8ca061b518464fc4ebe46092a984dc5980fe242724530602564736f6c63430008070033", + "deployedBytecode": "0x6080604052600436106100c65760003560e01c8063395093511161007f578063a457c2d711610059578063a457c2d71461021b578063a9059cbb1461023b578063d0e30db01461025b578063dd62ed3e1461026357600080fd5b806339509351146101b057806370a08231146101d057806395d89b411461020657600080fd5b806306fdde03146100da578063095ea7b31461010557806318160ddd1461013557806323b872dd146101545780632e1a7d4d14610174578063313ce5671461019457600080fd5b366100d5576100d3610283565b005b600080fd5b3480156100e657600080fd5b506100ef61028f565b6040516100fc9190610afb565b60405180910390f35b34801561011157600080fd5b50610125610120366004610ab8565b610321565b60405190151581526020016100fc565b34801561014157600080fd5b506002545b6040519081526020016100fc565b34801561016057600080fd5b5061012561016f366004610a7c565b610339565b34801561018057600080fd5b506100d361018f366004610ae2565b61035d565b3480156101a057600080fd5b50604051601281526020016100fc565b3480156101bc57600080fd5b506101256101cb366004610ab8565b6103fa565b3480156101dc57600080fd5b506101466101eb366004610a27565b6001600160a01b031660009081526020819052604090205490565b34801561021257600080fd5b506100ef61041c565b34801561022757600080fd5b50610125610236366004610ab8565b61042b565b34801561024757600080fd5b50610125610256366004610ab8565b6104a6565b6100d3610283565b34801561026f57600080fd5b5061014661027e366004610a49565b6104b4565b61028d33346104df565b565b60606003805461029e90610b76565b80601f01602080910402602001604051908101604052809291908181526020018280546102ca90610b76565b80156103175780601f106102ec57610100808354040283529160200191610317565b820191906000526020600020905b8154815290600101906020018083116102fa57829003601f168201915b5050505050905090565b60003361032f81858561059e565b5060019392505050565b6000336103478582856106c3565b61035285858561073d565b506001949350505050565b61036733826108e1565b604051600090339083908381818185875af1925050503d80600081146103a9576040519150601f19603f3d011682016040523d82523d6000602084013e6103ae565b606091505b50509050806103f65760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b60448201526064015b60405180910390fd5b5050565b60003361032f81858561040d83836104b4565b6104179190610b50565b61059e565b60606004805461029e90610b76565b6000338161043982866104b4565b9050838110156104995760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016103ed565b610352828686840361059e565b60003361032f81858561073d565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0382166105355760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103ed565b80600260008282546105479190610b50565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0383166106005760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016103ed565b6001600160a01b0382166106615760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016103ed565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006106cf84846104b4565b90506000198114610737578181101561072a5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103ed565b610737848484840361059e565b50505050565b6001600160a01b0383166107a15760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016103ed565b6001600160a01b0382166108035760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016103ed565b6001600160a01b0383166000908152602081905260409020548181101561087b5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016103ed565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610737565b6001600160a01b0382166109415760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016103ed565b6001600160a01b038216600090815260208190526040902054818110156109b55760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016103ed565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016106b6565b80356001600160a01b0381168114610a2257600080fd5b919050565b600060208284031215610a3957600080fd5b610a4282610a0b565b9392505050565b60008060408385031215610a5c57600080fd5b610a6583610a0b565b9150610a7360208401610a0b565b90509250929050565b600080600060608486031215610a9157600080fd5b610a9a84610a0b565b9250610aa860208501610a0b565b9150604084013590509250925092565b60008060408385031215610acb57600080fd5b610ad483610a0b565b946020939093013593505050565b600060208284031215610af457600080fd5b5035919050565b600060208083528351808285015260005b81811015610b2857858101830151858201604001528201610b0c565b81811115610b3a576000604083870101525b50601f01601f1916929092016040019392505050565b60008219821115610b7157634e487b7160e01b600052601160045260246000fd5b500190565b600181811c90821680610b8a57607f821691505b60208210811415610bab57634e487b7160e01b600052602260045260246000fd5b5091905056fea26469706673582212207934469329607db8ca061b518464fc4ebe46092a984dc5980fe242724530602564736f6c63430008070033", + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "name()": { + "details": "Returns the name of the token." + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "minimal \"wrapped eth\" implementation.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 8713, + "contract": "contracts-link/test/TestWrappedNativeToken.sol:TestWrappedNativeToken", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 8719, + "contract": "contracts-link/test/TestWrappedNativeToken.sol:TestWrappedNativeToken", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 8721, + "contract": "contracts-link/test/TestWrappedNativeToken.sol:TestWrappedNativeToken", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 8723, + "contract": "contracts-link/test/TestWrappedNativeToken.sol:TestWrappedNativeToken", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 8725, + "contract": "contracts-link/test/TestWrappedNativeToken.sol:TestWrappedNativeToken", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/gsn/deploy/data/deployments/amoy/solcInputs/766eaa539015b343a6f8732a84d5a9ae.json b/gsn/deploy/data/deployments/amoy/solcInputs/766eaa539015b343a6f8732a84d5a9ae.json new file mode 100644 index 00000000..6b66cb1a --- /dev/null +++ b/gsn/deploy/data/deployments/amoy/solcInputs/766eaa539015b343a6f8732a84d5a9ae.json @@ -0,0 +1,368 @@ +{ + "language": "Solidity", + "sources": { + "@opengsn/contracts/src/BasePaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\n\nimport \"./utils/GsnTypes.sol\";\nimport \"./interfaces/IPaymaster.sol\";\nimport \"./interfaces/IRelayHub.sol\";\nimport \"./utils/GsnEip712Library.sol\";\nimport \"./forwarder/IForwarder.sol\";\n\n/**\n * @notice An abstract base class to be inherited by a concrete Paymaster.\n * A subclass must implement:\n * - preRelayedCall\n * - postRelayedCall\n */\nabstract contract BasePaymaster is IPaymaster, Ownable, ERC165 {\n using ERC165Checker for address;\n\n IRelayHub internal relayHub;\n address private _trustedForwarder;\n\n /// @inheritdoc IPaymaster\n function getRelayHub() public override view returns (address) {\n return address(relayHub);\n }\n\n //overhead of forwarder verify+signature, plus hub overhead.\n uint256 constant public FORWARDER_HUB_OVERHEAD = 50000;\n\n //These parameters are documented in IPaymaster.GasAndDataLimits\n uint256 constant public PRE_RELAYED_CALL_GAS_LIMIT = 100000;\n uint256 constant public POST_RELAYED_CALL_GAS_LIMIT = 110000;\n uint256 constant public PAYMASTER_ACCEPTANCE_BUDGET = PRE_RELAYED_CALL_GAS_LIMIT + FORWARDER_HUB_OVERHEAD;\n uint256 constant public CALLDATA_SIZE_LIMIT = 10500;\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n return interfaceId == type(IPaymaster).interfaceId ||\n interfaceId == type(Ownable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IPaymaster\n function getGasAndDataLimits()\n public\n override\n virtual\n view\n returns (\n IPaymaster.GasAndDataLimits memory limits\n ) {\n return IPaymaster.GasAndDataLimits(\n PAYMASTER_ACCEPTANCE_BUDGET,\n PRE_RELAYED_CALL_GAS_LIMIT,\n POST_RELAYED_CALL_GAS_LIMIT,\n CALLDATA_SIZE_LIMIT\n );\n }\n\n /**\n * @notice this method must be called from preRelayedCall to validate that the forwarder\n * is approved by the paymaster as well as by the recipient contract.\n */\n function _verifyForwarder(GsnTypes.RelayRequest calldata relayRequest)\n internal\n virtual\n view\n {\n require(getTrustedForwarder() == relayRequest.relayData.forwarder, \"Forwarder is not trusted\");\n GsnEip712Library.verifyForwarderTrusted(relayRequest);\n }\n\n function _verifyRelayHubOnly() internal virtual view {\n require(msg.sender == getRelayHub(), \"can only be called by RelayHub\");\n }\n\n function _verifyValue(GsnTypes.RelayRequest calldata relayRequest) internal virtual view{\n require(relayRequest.request.value == 0, \"value transfer not supported\");\n }\n\n function _verifyPaymasterData(GsnTypes.RelayRequest calldata relayRequest) internal virtual view {\n require(relayRequest.relayData.paymasterData.length == 0, \"should have no paymasterData\");\n }\n\n function _verifyApprovalData(bytes calldata approvalData) internal virtual view{\n require(approvalData.length == 0, \"should have no approvalData\");\n }\n\n /**\n * @notice The owner of the Paymaster can change the instance of the RelayHub this Paymaster works with.\n * :warning: **Warning** :warning: The deposit on the previous RelayHub must be withdrawn first.\n */\n function setRelayHub(IRelayHub hub) public onlyOwner {\n require(address(hub).supportsInterface(type(IRelayHub).interfaceId), \"target is not a valid IRelayHub\");\n relayHub = hub;\n }\n\n /**\n * @notice The owner of the Paymaster can change the instance of the Forwarder this Paymaster works with.\n * @notice the Recipients must trust this Forwarder as well in order for the configuration to remain functional.\n */\n function setTrustedForwarder(address forwarder) public virtual onlyOwner {\n require(forwarder.supportsInterface(type(IForwarder).interfaceId), \"target is not a valid IForwarder\");\n _trustedForwarder = forwarder;\n }\n\n function getTrustedForwarder() public virtual view override returns (address){\n return _trustedForwarder;\n }\n\n /**\n * @notice Any native Ether transferred into the paymaster is transferred as a deposit to the RelayHub.\n * This way, we don't need to understand the RelayHub API in order to replenish the paymaster.\n */\n receive() external virtual payable {\n require(address(relayHub) != address(0), \"relay hub address not set\");\n relayHub.depositFor{value:msg.value}(address(this));\n }\n\n /**\n * @notice Withdraw deposit from the RelayHub.\n * @param amount The amount to be subtracted from the sender.\n * @param target The target to which the amount will be transferred.\n */\n function withdrawRelayHubDepositTo(uint256 amount, address payable target) public onlyOwner {\n relayHub.withdraw(target, amount);\n }\n\n /// @inheritdoc IPaymaster\n function preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n external\n override\n returns (bytes memory, bool) {\n _verifyRelayHubOnly();\n _verifyForwarder(relayRequest);\n _verifyValue(relayRequest);\n _verifyPaymasterData(relayRequest);\n _verifyApprovalData(approvalData);\n return _preRelayedCall(relayRequest, signature, approvalData, maxPossibleGas);\n }\n\n\n /**\n * @notice internal logic the paymasters need to provide to select which transactions they are willing to pay for\n * @notice see the documentation for `IPaymaster::preRelayedCall` for details\n */\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata,\n bytes calldata,\n bytes calldata,\n uint256\n )\n internal\n virtual\n returns (bytes memory, bool);\n\n /// @inheritdoc IPaymaster\n function postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n external\n override\n {\n _verifyRelayHubOnly();\n _postRelayedCall(context, success, gasUseWithoutPost, relayData);\n }\n\n /**\n * @notice internal logic the paymasters need to provide if they need to take some action after the transaction\n * @notice see the documentation for `IPaymaster::postRelayedCall` for details\n */\n function _postRelayedCall(\n bytes calldata,\n bool,\n uint256,\n GsnTypes.RelayData calldata\n )\n internal\n virtual;\n}\n" + }, + "@opengsn/contracts/src/ERC2771Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable no-inline-assembly\npragma solidity >=0.6.9;\n\nimport \"./interfaces/IERC2771Recipient.sol\";\n\n/**\n * @title The ERC-2771 Recipient Base Abstract Class - Implementation\n *\n * @notice Note that this contract was called `BaseRelayRecipient` in the previous revision of the GSN.\n *\n * @notice A base contract to be inherited by any contract that want to receive relayed transactions.\n *\n * @notice A subclass must use `_msgSender()` instead of `msg.sender`.\n */\nabstract contract ERC2771Recipient is IERC2771Recipient {\n\n /*\n * Forwarder singleton we accept calls from\n */\n address private _trustedForwarder;\n\n /**\n * :warning: **Warning** :warning: The Forwarder can have a full control over your Recipient. Only trust verified Forwarder.\n * @notice Method is not a required method to allow Recipients to trust multiple Forwarders. Not recommended yet.\n * @return forwarder The address of the Forwarder contract that is being used.\n */\n function getTrustedForwarder() public virtual view returns (address forwarder){\n return _trustedForwarder;\n }\n\n function _setTrustedForwarder(address _forwarder) internal {\n _trustedForwarder = _forwarder;\n }\n\n /// @inheritdoc IERC2771Recipient\n function isTrustedForwarder(address forwarder) public virtual override view returns(bool) {\n return forwarder == _trustedForwarder;\n }\n\n /// @inheritdoc IERC2771Recipient\n function _msgSender() internal override virtual view returns (address ret) {\n if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // so we trust that the last bytes of msg.data are the verified sender address.\n // extract sender address from the end of msg.data\n assembly {\n ret := shr(96,calldataload(sub(calldatasize(),20)))\n }\n } else {\n ret = msg.sender;\n }\n }\n\n /// @inheritdoc IERC2771Recipient\n function _msgData() internal override virtual view returns (bytes calldata ret) {\n if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) {\n return msg.data[0:msg.data.length-20];\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@opengsn/contracts/src/forwarder/Forwarder.sol": { + "content": "// solhint-disable not-rely-on-time\n// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\n// #if ENABLE_CONSOLE_LOG\nimport \"hardhat/console.sol\";\n// #endif\n\nimport \"./IForwarder.sol\";\n\n/**\n * @title The Forwarder Implementation\n * @notice This implementation of the `IForwarder` interface uses ERC-712 signatures and stored nonces for verification.\n */\ncontract Forwarder is IForwarder, ERC165 {\n using ECDSA for bytes32;\n\n address private constant DRY_RUN_ADDRESS = 0x0000000000000000000000000000000000000000;\n\n string public constant GENERIC_PARAMS = \"address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data,uint256 validUntilTime\";\n\n string public constant EIP712_DOMAIN_TYPE = \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\";\n\n mapping(bytes32 => bool) public typeHashes;\n mapping(bytes32 => bool) public domains;\n\n // Nonces of senders, used to prevent replay attacks\n mapping(address => uint256) private nonces;\n\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n\n /// @inheritdoc IForwarder\n function getNonce(address from)\n public view override\n returns (uint256) {\n return nonces[from];\n }\n\n constructor() {\n string memory requestType = string(abi.encodePacked(\"ForwardRequest(\", GENERIC_PARAMS, \")\"));\n registerRequestTypeInternal(requestType);\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n return interfaceId == type(IForwarder).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IForwarder\n function verify(\n ForwardRequest calldata req,\n bytes32 domainSeparator,\n bytes32 requestTypeHash,\n bytes calldata suffixData,\n bytes calldata sig)\n external override view {\n _verifyNonce(req);\n _verifySig(req, domainSeparator, requestTypeHash, suffixData, sig);\n }\n\n /// @inheritdoc IForwarder\n function execute(\n ForwardRequest calldata req,\n bytes32 domainSeparator,\n bytes32 requestTypeHash,\n bytes calldata suffixData,\n bytes calldata sig\n )\n external payable\n override\n returns (bool success, bytes memory ret) {\n _verifySig(req, domainSeparator, requestTypeHash, suffixData, sig);\n _verifyAndUpdateNonce(req);\n\n require(req.validUntilTime == 0 || req.validUntilTime > block.timestamp, \"FWD: request expired\");\n\n uint256 gasForTransfer = 0;\n if ( req.value != 0 ) {\n gasForTransfer = 40000; //buffer in case we need to move eth after the transaction.\n }\n bytes memory callData = abi.encodePacked(req.data, req.from);\n require(gasleft()*63/64 >= req.gas + gasForTransfer, \"FWD: insufficient gas\");\n // solhint-disable-next-line avoid-low-level-calls\n (success,ret) = req.to.call{gas : req.gas, value : req.value}(callData);\n\n // #if ENABLE_CONSOLE_LOG\n console.log(\"execute result: success: %s ret:\", success);\n console.logBytes(ret);\n // #endif\n\n if ( req.value != 0 && address(this).balance>0 ) {\n // can't fail: req.from signed (off-chain) the request, so it must be an EOA...\n payable(req.from).transfer(address(this).balance);\n }\n\n return (success,ret);\n }\n\n function _verifyNonce(ForwardRequest calldata req) internal view {\n require(nonces[req.from] == req.nonce, \"FWD: nonce mismatch\");\n }\n\n function _verifyAndUpdateNonce(ForwardRequest calldata req) internal {\n require(nonces[req.from]++ == req.nonce, \"FWD: nonce mismatch\");\n }\n\n /// @inheritdoc IForwarder\n function registerRequestType(string calldata typeName, string calldata typeSuffix) external override {\n\n for (uint256 i = 0; i < bytes(typeName).length; i++) {\n bytes1 c = bytes(typeName)[i];\n require(c != \"(\" && c != \")\", \"FWD: invalid typename\");\n }\n\n string memory requestType = string(abi.encodePacked(typeName, \"(\", GENERIC_PARAMS, \",\", typeSuffix));\n registerRequestTypeInternal(requestType);\n }\n\n /// @inheritdoc IForwarder\n function registerDomainSeparator(string calldata name, string calldata version) external override {\n uint256 chainId;\n /* solhint-disable-next-line no-inline-assembly */\n assembly { chainId := chainid() }\n\n bytes memory domainValue = abi.encode(\n keccak256(bytes(EIP712_DOMAIN_TYPE)),\n keccak256(bytes(name)),\n keccak256(bytes(version)),\n chainId,\n address(this));\n\n bytes32 domainHash = keccak256(domainValue);\n\n domains[domainHash] = true;\n emit DomainRegistered(domainHash, domainValue);\n }\n\n function registerRequestTypeInternal(string memory requestType) internal {\n\n bytes32 requestTypehash = keccak256(bytes(requestType));\n typeHashes[requestTypehash] = true;\n emit RequestTypeRegistered(requestTypehash, requestType);\n }\n\n function _verifySig(\n ForwardRequest calldata req,\n bytes32 domainSeparator,\n bytes32 requestTypeHash,\n bytes calldata suffixData,\n bytes calldata sig)\n internal\n virtual\n view\n {\n require(domains[domainSeparator], \"FWD: unregistered domain sep.\");\n require(typeHashes[requestTypeHash], \"FWD: unregistered typehash\");\n bytes32 digest = keccak256(abi.encodePacked(\n \"\\x19\\x01\", domainSeparator,\n keccak256(_getEncoded(req, requestTypeHash, suffixData))\n ));\n // solhint-disable-next-line avoid-tx-origin\n require(tx.origin == DRY_RUN_ADDRESS || digest.recover(sig) == req.from, \"FWD: signature mismatch\");\n }\n\n /**\n * @notice Creates a byte array that is a valid ABI encoding of a request of a `RequestType` type. See `execute()`.\n */\n function _getEncoded(\n ForwardRequest calldata req,\n bytes32 requestTypeHash,\n bytes calldata suffixData\n )\n public\n pure\n returns (\n bytes memory\n ) {\n // we use encodePacked since we append suffixData as-is, not as dynamic param.\n // still, we must make sure all first params are encoded as abi.encode()\n // would encode them - as 256-bit-wide params.\n return abi.encodePacked(\n requestTypeHash,\n uint256(uint160(req.from)),\n uint256(uint160(req.to)),\n req.value,\n req.gas,\n req.nonce,\n keccak256(req.data),\n req.validUntilTime,\n suffixData\n );\n }\n}\n" + }, + "@opengsn/contracts/src/forwarder/IForwarder.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport \"@openzeppelin/contracts/interfaces/IERC165.sol\";\n\n/**\n * @title The Forwarder Interface\n * @notice The contracts implementing this interface take a role of authorization, authentication and replay protection\n * for contracts that choose to trust a `Forwarder`, instead of relying on a mechanism built into the Ethereum protocol.\n *\n * @notice if the `Forwarder` contract decides that an incoming `ForwardRequest` is valid, it must append 20 bytes that\n * represent the caller to the `data` field of the request and send this new data to the target address (the `to` field)\n *\n * :warning: **Warning** :warning: The Forwarder can have a full control over a `Recipient` contract.\n * Any vulnerability in a `Forwarder` implementation can make all of its `Recipient` contracts susceptible!\n * Recipient contracts should only trust forwarders that passed through security audit,\n * otherwise they are susceptible to identity theft.\n */\ninterface IForwarder is IERC165 {\n\n /**\n * @notice A representation of a request for a `Forwarder` to send `data` on behalf of a `from` to a target (`to`).\n */\n struct ForwardRequest {\n address from;\n address to;\n uint256 value;\n uint256 gas;\n uint256 nonce;\n bytes data;\n uint256 validUntilTime;\n }\n\n event DomainRegistered(bytes32 indexed domainSeparator, bytes domainValue);\n\n event RequestTypeRegistered(bytes32 indexed typeHash, string typeStr);\n\n /**\n * @param from The address of a sender.\n * @return The nonce for this address.\n */\n function getNonce(address from)\n external view\n returns(uint256);\n\n /**\n * @notice Verify the transaction is valid and can be executed.\n * Implementations must validate the signature and the nonce of the request are correct.\n * Does not revert and returns successfully if the input is valid.\n * Reverts if any validation has failed. For instance, if either signature or nonce are incorrect.\n * Reverts if `domainSeparator` or `requestTypeHash` are not registered as well.\n */\n function verify(\n ForwardRequest calldata forwardRequest,\n bytes32 domainSeparator,\n bytes32 requestTypeHash,\n bytes calldata suffixData,\n bytes calldata signature\n ) external view;\n\n /**\n * @notice Executes a transaction specified by the `ForwardRequest`.\n * The transaction is first verified and then executed.\n * The success flag and returned bytes array of the `CALL` are returned as-is.\n *\n * This method would revert only in case of a verification error.\n *\n * All the target errors are reported using the returned success flag and returned bytes array.\n *\n * @param forwardRequest All requested transaction parameters.\n * @param domainSeparator The domain used when signing this request.\n * @param requestTypeHash The request type used when signing this request.\n * @param suffixData The ABI-encoded extension data for the current `RequestType` used when signing this request.\n * @param signature The client signature to be validated.\n *\n * @return success The success flag of the underlying `CALL` to the target address.\n * @return ret The byte array returned by the underlying `CALL` to the target address.\n */\n function execute(\n ForwardRequest calldata forwardRequest,\n bytes32 domainSeparator,\n bytes32 requestTypeHash,\n bytes calldata suffixData,\n bytes calldata signature\n )\n external payable\n returns (bool success, bytes memory ret);\n\n /**\n * @notice Register a new Request typehash.\n *\n * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\n *\n * @param typeName The name of the request type.\n * @param typeSuffix Any extra data after the generic params. Must contain add at least one param.\n * The generic ForwardRequest type is always registered by the constructor.\n */\n function registerRequestType(string calldata typeName, string calldata typeSuffix) external;\n\n /**\n * @notice Register a new domain separator.\n *\n * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\n *\n * @notice The domain separator must have the following fields: `name`, `version`, `chainId`, `verifyingContract`.\n * The `chainId` is the current network's `chainId`, and the `verifyingContract` is this Forwarder's address.\n * This method accepts the domain name and version to create and register the domain separator value.\n * @param name The domain's display name.\n * @param version The domain/protocol version.\n */\n function registerDomainSeparator(string calldata name, string calldata version) external;\n}\n" + }, + "@opengsn/contracts/src/interfaces/IERC2771Recipient.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0;\n\n/**\n * @title The ERC-2771 Recipient Base Abstract Class - Declarations\n *\n * @notice A contract must implement this interface in order to support relayed transaction.\n *\n * @notice It is recommended that your contract inherits from the ERC2771Recipient contract.\n */\nabstract contract IERC2771Recipient {\n\n /**\n * :warning: **Warning** :warning: The Forwarder can have a full control over your Recipient. Only trust verified Forwarder.\n * @param forwarder The address of the Forwarder contract that is being used.\n * @return isTrustedForwarder `true` if the Forwarder is trusted to forward relayed transactions by this Recipient.\n */\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\n\n /**\n * @notice Use this method the contract anywhere instead of msg.sender to support relayed transactions.\n * @return sender The real sender of this call.\n * For a call that came through the Forwarder the real sender is extracted from the last 20 bytes of the `msg.data`.\n * Otherwise simply returns `msg.sender`.\n */\n function _msgSender() internal virtual view returns (address);\n\n /**\n * @notice Use this method in the contract instead of `msg.data` when difference matters (hashing, signature, etc.)\n * @return data The real `msg.data` of this call.\n * For a call that came through the Forwarder, the real sender address was appended as the last 20 bytes\n * of the `msg.data` - so this method will strip those 20 bytes off.\n * Otherwise (if the call was made directly and not through the forwarder) simply returns `msg.data`.\n */\n function _msgData() internal virtual view returns (bytes calldata);\n}\n" + }, + "@opengsn/contracts/src/interfaces/IPaymaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport \"@openzeppelin/contracts/interfaces/IERC165.sol\";\n\nimport \"../utils/GsnTypes.sol\";\n\n/**\n * @title The Paymaster Interface\n * @notice Contracts implementing this interface exist to make decision about paying the transaction fee to the relay.\n *\n * @notice There are two callbacks here that are executed by the RelayHub: `preRelayedCall` and `postRelayedCall`.\n *\n * @notice It is recommended that your implementation inherits from the abstract BasePaymaster contract.\n*/\ninterface IPaymaster is IERC165 {\n /**\n * @notice The limits this Paymaster wants to be imposed by the RelayHub on user input. See `getGasAndDataLimits`.\n */\n struct GasAndDataLimits {\n uint256 acceptanceBudget;\n uint256 preRelayedCallGasLimit;\n uint256 postRelayedCallGasLimit;\n uint256 calldataSizeLimit;\n }\n\n /**\n * @notice Return the Gas Limits for Paymaster's functions and maximum msg.data length values for this Paymaster.\n * This function allows different paymasters to have different properties without changes to the RelayHub.\n * @return limits An instance of the `GasAndDataLimits` struct\n *\n * ##### `acceptanceBudget`\n * If the transactions consumes more than `acceptanceBudget` this Paymaster will be charged for gas no matter what.\n * Transaction that gets rejected after consuming more than `acceptanceBudget` gas is on this Paymaster's expense.\n *\n * Should be set to an amount gas this Paymaster expects to spend deciding whether to accept or reject a request.\n * This includes gas consumed by calculations in the `preRelayedCall`, `Forwarder` and the recipient contract.\n *\n * :warning: **Warning** :warning: As long this value is above `preRelayedCallGasLimit`\n * (see defaults in `BasePaymaster`), the Paymaster is guaranteed it will never pay for rejected transactions.\n * If this value is below `preRelayedCallGasLimit`, it might might make Paymaster open to a \"griefing\" attack.\n *\n * The relayers should prefer lower `acceptanceBudget`, as it improves their chances of being compensated.\n * From a Relay's point of view, this is the highest gas value a bad Paymaster may cost the relay,\n * since the paymaster will pay anything above that value regardless of whether the transaction succeeds or reverts.\n * Specifying value too high might make the call rejected by relayers (see `maxAcceptanceBudget` in server config).\n *\n * ##### `preRelayedCallGasLimit`\n * The max gas usage of preRelayedCall. Any revert of the `preRelayedCall` is a request rejection by the paymaster.\n * As long as `acceptanceBudget` is above `preRelayedCallGasLimit`, any such revert is not payed by the paymaster.\n *\n * ##### `postRelayedCallGasLimit`\n * The max gas usage of postRelayedCall. The Paymaster is not charged for the maximum, only for actually used gas.\n * Note that an OOG will revert the inner transaction, but the paymaster will be charged for it anyway.\n */\n function getGasAndDataLimits()\n external\n view\n returns (\n GasAndDataLimits memory limits\n );\n\n /**\n * @notice :warning: **Warning** :warning: using incorrect Forwarder may cause the Paymaster to agreeing to pay for invalid transactions.\n * @return trustedForwarder The address of the `Forwarder` that is trusted by this Paymaster to execute the requests.\n */\n function getTrustedForwarder() external view returns (address trustedForwarder);\n\n /**\n * @return relayHub The address of the `RelayHub` that is trusted by this Paymaster to execute the requests.\n */\n function getRelayHub() external view returns (address relayHub);\n\n /**\n * @notice Called by the Relay in view mode and later by the `RelayHub` on-chain to validate that\n * the Paymaster agrees to pay for this call.\n *\n * The request is considered to be rejected by the Paymaster in one of the following conditions:\n * - `preRelayedCall()` method reverts\n * - the `Forwarder` reverts because of nonce or signature error\n * - the `Paymaster` returned `rejectOnRecipientRevert: true` and the recipient contract reverted\n * (and all that did not consume more than `acceptanceBudget` gas).\n *\n * In any of the above cases, all Paymaster calls and the recipient call are reverted.\n * In any other case the Paymaster will pay for the gas cost of the transaction.\n * Note that even if `postRelayedCall` is reverted the Paymaster will be charged.\n *\n\n * @param relayRequest - the full relay request structure\n * @param signature - user's EIP712-compatible signature of the `relayRequest`.\n * Note that in most cases the paymaster shouldn't try use it at all. It is always checked\n * by the forwarder immediately after preRelayedCall returns.\n * @param approvalData - extra dapp-specific data (e.g. signature from trusted party)\n * @param maxPossibleGas - based on values returned from `getGasAndDataLimits`\n * the RelayHub will calculate the maximum possible amount of gas the user may be charged for.\n * In order to convert this value to wei, the Paymaster has to call \"relayHub.calculateCharge()\"\n *\n * @return context\n * A byte array to be passed to postRelayedCall.\n * Can contain any data needed by this Paymaster in any form or be empty if no extra data is needed.\n * @return rejectOnRecipientRevert\n * The flag that allows a Paymaster to \"delegate\" the rejection to the recipient code.\n * It also means the Paymaster trust the recipient to reject fast: both preRelayedCall,\n * forwarder check and recipient checks must fit into the GasLimits.acceptanceBudget,\n * otherwise the TX is paid by the Paymaster.\n * `true` if the Paymaster wants to reject the TX if the recipient reverts.\n * `false` if the Paymaster wants rejects by the recipient to be completed on chain and paid by the Paymaster.\n */\n function preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n external\n returns (bytes memory context, bool rejectOnRecipientRevert);\n\n /**\n * @notice This method is called after the actual relayed function call.\n * It may be used to record the transaction (e.g. charge the caller by some contract logic) for this call.\n *\n * Revert in this functions causes a revert of the client's relayed call (and preRelayedCall(), but the Paymaster\n * is still committed to pay the relay for the entire transaction.\n *\n * @param context The call context, as returned by the preRelayedCall\n * @param success `true` if the relayed call succeeded, false if it reverted\n * @param gasUseWithoutPost The actual amount of gas used by the entire transaction, EXCEPT\n * the gas used by the postRelayedCall itself.\n * @param relayData The relay params of the request. can be used by relayHub.calculateCharge()\n *\n */\n function postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n ) external;\n\n /**\n * @return version The SemVer string of this Paymaster's version.\n */\n function versionPaymaster() external view returns (string memory);\n}\n" + }, + "@opengsn/contracts/src/interfaces/IPenalizer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity >=0.7.6;\n\nimport \"./IRelayHub.sol\";\n\n/**\n * @title The Penalizer Interface\n * @notice In some cases the behavior of a Relay Server may be found to be illegal.\n * It is the responsibility of a `Penalizer` contract to judge whether there was a penalizable event.\n *\n * @notice In case there was, the `Penalizer` will direct the `RelayHub` to slash the stake of the faulty Relay Server.\n */\ninterface IPenalizer is IERC165 {\n\n /// @notice Emitted once the reporter submits the first step in the commit-reveal process.\n event CommitAdded(address indexed sender, bytes32 indexed commitHash, uint256 readyBlockNumber);\n\n struct Transaction {\n uint256 nonce;\n uint256 gasLimit;\n address to;\n uint256 value;\n bytes data;\n }\n\n /**\n * @notice Called by the reporter as the first step in the commit-reveal process.\n * Any sender can call it to make sure no-one can front-run it to claim this penalization.\n * @param commitHash The hash of the report of a penalizable behaviour the reporter wants to reveal.\n * Calculated as `commit(keccak(encodedPenalizeFunction))`.\n */\n function commit(bytes32 commitHash) external;\n\n /**\n * @notice Called by the reporter as the second step in the commit-reveal process.\n * If a Relay Worker attacked the system by signing multiple transactions with same nonce so only one is accepted,\n * anyone can grab both transactions from the blockchain and submit them here.\n * Check whether `unsignedTx1` != `unsignedTx2`, that both are signed by the same address,\n * and that `unsignedTx1.nonce` == `unsignedTx2.nonce`.\n * If all conditions are met, relay is considered an \"offending relay\".\n * The offending relay will be unregistered immediately, its stake will be forfeited and given\n * to the address who reported it (the `msg.sender`), thus incentivizing anyone to report offending relays.\n */\n function penalizeRepeatedNonce(\n bytes calldata unsignedTx1,\n bytes calldata signature1,\n bytes calldata unsignedTx2,\n bytes calldata signature2,\n IRelayHub hub,\n uint256 randomValue\n ) external;\n\n /**\n * @notice Called by the reporter as the second step in the commit-reveal process.\n * The Relay Workers are not allowed to make calls other than to the `relayCall` method.\n */\n function penalizeIllegalTransaction(\n bytes calldata unsignedTx,\n bytes calldata signature,\n IRelayHub hub,\n uint256 randomValue\n ) external;\n\n /// @return a SemVer-compliant version of the `Penalizer` contract.\n function versionPenalizer() external view returns (string memory);\n\n /// @return The minimum delay between commit and reveal steps.\n function getPenalizeBlockDelay() external view returns (uint256);\n\n /// @return The maximum delay between commit and reveal steps.\n function getPenalizeBlockExpiration() external view returns (uint256);\n}\n" + }, + "@opengsn/contracts/src/interfaces/IRelayHub.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport \"@openzeppelin/contracts/interfaces/IERC165.sol\";\n\nimport \"../utils/GsnTypes.sol\";\nimport \"./IStakeManager.sol\";\n\n/**\n * @title The RelayHub interface\n * @notice The implementation of this interface provides all the information the GSN client needs to\n * create a valid `RelayRequest` and also serves as an entry point for such requests.\n *\n * @notice The RelayHub also handles all the related financial records and hold the balances of participants.\n * The Paymasters keep their Ether deposited in the `RelayHub` in order to pay for the `RelayRequest`s that thay choose\n * to pay for, and Relay Servers keep their earned Ether in the `RelayHub` until they choose to `withdraw()`\n *\n * @notice The RelayHub on each supported network only needs a single instance and there is usually no need for dApp\n * developers or Relay Server operators to redeploy, reimplement, modify or override the `RelayHub`.\n */\ninterface IRelayHub is IERC165 {\n /**\n * @notice A struct that contains all the parameters of the `RelayHub` that can be modified after the deployment.\n */\n struct RelayHubConfig {\n // maximum number of worker accounts allowed per manager\n uint256 maxWorkerCount;\n // Gas set aside for all relayCall() instructions to prevent unexpected out-of-gas exceptions\n uint256 gasReserve;\n // Gas overhead to calculate gasUseWithoutPost\n uint256 postOverhead;\n // Gas cost of all relayCall() instructions after actual 'calculateCharge()'\n // Assume that relay has non-zero balance (costs 15'000 more otherwise).\n uint256 gasOverhead;\n // Minimum unstake delay seconds of a relay manager's stake on the StakeManager\n uint256 minimumUnstakeDelay;\n // Developers address\n address devAddress;\n // 0 < fee < 100, as percentage of total charge from paymaster to relayer\n uint8 devFee;\n // baseRelayFee The base fee the Relay Server charges for a single transaction in Ether, in wei.\n uint80 baseRelayFee;\n // pctRelayFee The percent of the total charge to add as a Relay Server fee to the total charge.\n uint16 pctRelayFee;\n }\n\n /// @notice Emitted when a configuration of the `RelayHub` is changed\n event RelayHubConfigured(RelayHubConfig config);\n\n /// @notice Emitted when relays are added by a relayManager\n event RelayWorkersAdded(\n address indexed relayManager,\n address[] newRelayWorkers,\n uint256 workersCount\n );\n\n /// @notice Emitted when an account withdraws funds from the `RelayHub`.\n event Withdrawn(\n address indexed account,\n address indexed dest,\n uint256 amount\n );\n\n /// @notice Emitted when `depositFor` is called, including the amount and account that was funded.\n event Deposited(\n address indexed paymaster,\n address indexed from,\n uint256 amount\n );\n\n /// @notice Emitted for each token configured for staking in setMinimumStakes\n event StakingTokenDataChanged(\n address token,\n uint256 minimumStake\n );\n\n /**\n * @notice Emitted when an attempt to relay a call fails and the `Paymaster` does not accept the transaction.\n * The actual relayed call was not executed, and the recipient not charged.\n * @param reason contains a revert reason returned from preRelayedCall or forwarder.\n */\n event TransactionRejectedByPaymaster(\n address indexed relayManager,\n address indexed paymaster,\n bytes32 indexed relayRequestID,\n address from,\n address to,\n address relayWorker,\n bytes4 selector,\n uint256 innerGasUsed,\n bytes reason\n );\n\n /**\n * @notice Emitted when a transaction is relayed. Note that the actual internal function call might be reverted.\n * The reason for a revert will be indicated in the `status` field of a corresponding `RelayCallStatus` value.\n * @notice `charge` is the Ether value deducted from the `Paymaster` balance.\n * The amount added to the `relayManager` balance will be lower if there is an activated `devFee` in the `config`.\n */\n event TransactionRelayed(\n address indexed relayManager,\n address indexed relayWorker,\n bytes32 indexed relayRequestID,\n address from,\n address to,\n address paymaster,\n bytes4 selector,\n RelayCallStatus status,\n uint256 charge\n );\n\n /// @notice This event is emitted in case the internal function returns a value or reverts with a revert string.\n event TransactionResult(\n RelayCallStatus status,\n bytes returnValue\n );\n\n /// @notice This event is emitted in case this `RelayHub` is deprecated and will stop serving transactions soon.\n event HubDeprecated(uint256 deprecationTime);\n\n /**\n * @notice This event is emitted in case a `relayManager` has been deemed \"abandoned\" for being\n * unresponsive for a prolonged period of time.\n * @notice This event means the entire balance of the relay has been transferred to the `devAddress`.\n */\n event AbandonedRelayManagerBalanceEscheated(\n address indexed relayManager,\n uint256 balance\n );\n\n /**\n * Error codes that describe all possible failure reasons reported in the `TransactionRelayed` event `status` field.\n * @param OK The transaction was successfully relayed and execution successful - never included in the event.\n * @param RelayedCallFailed The transaction was relayed, but the relayed call failed.\n * @param RejectedByPreRelayed The transaction was not relayed due to preRelatedCall reverting.\n * @param RejectedByForwarder The transaction was not relayed due to forwarder check (signature,nonce).\n * @param PostRelayedFailed The transaction was relayed and reverted due to postRelatedCall reverting.\n * @param PaymasterBalanceChanged The transaction was relayed and reverted due to the paymaster balance change.\n */\n enum RelayCallStatus {\n OK,\n RelayedCallFailed,\n RejectedByPreRelayed,\n RejectedByForwarder,\n RejectedByRecipientRevert,\n PostRelayedFailed,\n PaymasterBalanceChanged\n }\n\n /**\n * @notice Add new worker addresses controlled by the sender who must be a staked Relay Manager address.\n * Emits a `RelayWorkersAdded` event.\n * This function can be called multiple times, emitting new events.\n */\n function addRelayWorkers(address[] calldata newRelayWorkers) external;\n\n /**\n * @notice The `RelayRegistrar` callback to notify the `RelayHub` that this `relayManager` has updated registration.\n */\n function onRelayServerRegistered(address relayManager) external;\n\n // Balance management\n\n /**\n * @notice Deposits ether for a `Paymaster`, so that it can and pay for relayed transactions.\n * :warning: **Warning** :warning: Unused balance can only be withdrawn by the holder itself, by calling `withdraw`.\n * Emits a `Deposited` event.\n */\n function depositFor(address target) external payable;\n\n /**\n * @notice Withdraws from an account's balance, sending it back to the caller.\n * Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding.\n * Emits a `Withdrawn` event.\n */\n function withdraw(address payable dest, uint256 amount) external;\n\n /**\n * @notice Withdraws from an account's balance, sending funds to multiple provided addresses.\n * Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding.\n * Emits a `Withdrawn` event for each destination.\n */\n function withdrawMultiple(address payable[] memory dest, uint256[] memory amount) external;\n\n // Relaying\n\n\n /**\n * @notice Relays a transaction. For this to succeed, multiple conditions must be met:\n * - `Paymaster`'s `preRelayCall` method must succeed and not revert.\n * - the `msg.sender` must be a registered Relay Worker that the user signed to use.\n * - the transaction's gas fees must be equal or larger than the ones that were signed by the sender.\n * - the transaction must have enough gas to run all internal transactions if they use all gas available to them.\n * - the `Paymaster` must have enough balance to pay the Relay Worker if all gas is spent.\n *\n * @notice If all conditions are met, the call will be relayed and the `Paymaster` charged.\n *\n * @param domainSeparatorName The name of the Domain Separator used to verify the EIP-712 signature\n * @param maxAcceptanceBudget The maximum valid value for `paymaster.getGasLimits().acceptanceBudget` to return.\n * @param relayRequest All details of the requested relayed call.\n * @param signature The client's EIP-712 signature over the `relayRequest` struct.\n * @param approvalData The dapp-specific data forwarded to the `Paymaster`'s `preRelayedCall` method.\n * This value is **not** verified by the `RelayHub` in any way.\n * As an example, it can be used to pass some kind of a third-party signature to the `Paymaster` for verification.\n *\n * Emits a `TransactionRelayed` event regardless of whether the transaction succeeded or failed.\n */\n function relayCall(\n string calldata domainSeparatorName,\n uint256 maxAcceptanceBudget,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData\n )\n external\n returns (\n bool paymasterAccepted,\n uint256 charge,\n IRelayHub.RelayCallStatus status,\n bytes memory returnValue\n );\n\n /**\n * @notice In case the Relay Worker has been found to be in violation of some rules by the `Penalizer` contract,\n * the `Penalizer` will call this method to execute a penalization.\n * The `RelayHub` will look up the Relay Manager of the given Relay Worker and will forward the call to\n * the `StakeManager` contract. The `RelayHub` does not perform the actual penalization either.\n * @param relayWorker The address of the Relay Worker that committed a penalizable offense.\n * @param beneficiary The address that called the `Penalizer` and will receive a reward for it.\n */\n function penalize(address relayWorker, address payable beneficiary) external;\n\n /**\n * @notice Sets or changes the configuration of this `RelayHub`.\n * @param _config The new configuration.\n */\n function setConfiguration(RelayHubConfig memory _config) external;\n\n /**\n * @notice Sets or changes the minimum amount of a given `token` that needs to be staked so that the Relay Manager\n * is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.\n * @param token An array of addresses of ERC-20 compatible tokens.\n * @param minimumStake An array of minimal amounts necessary for a corresponding token, in wei.\n */\n function setMinimumStakes(IERC20[] memory token, uint256[] memory minimumStake) external;\n\n /**\n * @notice Deprecate hub by reverting all incoming `relayCall()` calls starting from a given timestamp\n * @param _deprecationTime The timestamp in seconds after which the `RelayHub` stops serving transactions.\n */\n function deprecateHub(uint256 _deprecationTime) external;\n\n /**\n * @notice\n * @param relayManager\n */\n function escheatAbandonedRelayBalance(address relayManager) external;\n\n /**\n * @notice The fee is expressed as a base fee in wei plus percentage of the actual charge.\n * For example, a value '40' stands for a 40% fee, so the recipient will be charged for 1.4 times the spent amount.\n * @param gasUsed An amount of gas used by the transaction.\n * @param relayData The details of a transaction signed by the sender.\n * @return The calculated charge, in wei.\n */\n function calculateCharge(uint256 gasUsed, GsnTypes.RelayData calldata relayData) external view returns (uint256);\n\n /**\n * @notice The fee is expressed as a percentage of the actual charge.\n * For example, a value '40' stands for a 40% fee, so the Relay Manager will only get 60% of the `charge`.\n * @param charge The amount of Ether in wei the Paymaster will be charged for this transaction.\n * @return The calculated devFee, in wei.\n */\n function calculateDevCharge(uint256 charge) external view returns (uint256);\n /* getters */\n\n /// @return config The configuration of the `RelayHub`.\n function getConfiguration() external view returns (RelayHubConfig memory config);\n\n /**\n * @param token An address of an ERC-20 compatible tokens.\n * @return The minimum amount of a given `token` that needs to be staked so that the Relay Manager\n * is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.\n */\n function getMinimumStakePerToken(IERC20 token) external view returns (uint256);\n\n /**\n * @param worker An address of the Relay Worker.\n * @return The address of its Relay Manager.\n */\n function getWorkerManager(address worker) external view returns (address);\n\n /**\n * @param manager An address of the Relay Manager.\n * @return The count of Relay Workers associated with this Relay Manager.\n */\n function getWorkerCount(address manager) external view returns (uint256);\n\n /// @return An account's balance. It can be either a deposit of a `Paymaster`, or a revenue of a Relay Manager.\n function balanceOf(address target) external view returns (uint256);\n\n /// @return The `StakeManager` address for this `RelayHub`.\n function getStakeManager() external view returns (IStakeManager);\n\n /// @return The `Penalizer` address for this `RelayHub`.\n function getPenalizer() external view returns (address);\n\n /// @return The `RelayRegistrar` address for this `RelayHub`.\n function getRelayRegistrar() external view returns (address);\n\n /// @return The `BatchGateway` address for this `RelayHub`.\n function getBatchGateway() external view returns (address);\n\n /**\n * @notice Uses `StakeManager` to decide if the Relay Manager can be considered staked or not.\n * Returns if the stake's token, amount and delay satisfy all requirements, reverts otherwise.\n */\n function verifyRelayManagerStaked(address relayManager) external view;\n\n /**\n * @notice Uses `StakeManager` to check if the Relay Manager can be considered abandoned or not.\n * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\n */\n function isRelayEscheatable(address relayManager) external view returns (bool);\n\n /// @return `true` if the `RelayHub` is deprecated, `false` it it is not deprecated and can serve transactions.\n function isDeprecated() external view returns (bool);\n\n /// @return The timestamp from which the hub no longer allows relaying calls.\n function getDeprecationTime() external view returns (uint256);\n\n /// @return The block number in which the contract has been deployed.\n function getCreationBlock() external view returns (uint256);\n\n /// @return a SemVer-compliant version of the `RelayHub` contract.\n function versionHub() external view returns (string memory);\n\n /// @return A total measurable amount of gas left to current execution. Same as 'gasleft()' for pure EVMs.\n function aggregateGasleft() external view returns (uint256);\n}\n\n" + }, + "@opengsn/contracts/src/interfaces/IRelayRegistrar.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.6;\n\nimport \"@openzeppelin/contracts/interfaces/IERC165.sol\";\n\n/**\n * @title The RelayRegistrar Interface\n * @notice The on-chain registrar for all registered Relay Managers.\n *\n * @notice The client can use an implementation of a `RelayRegistrar` to find relay registration info.\n *\n */\ninterface IRelayRegistrar is IERC165 {\n\n /**\n * @notice A struct containing all the information necessary to client to interact with the Relay Server.\n */\n struct RelayInfo {\n //last registration block number\n uint32 lastSeenBlockNumber;\n //last registration block timestamp\n uint40 lastSeenTimestamp;\n //stake (first registration) block number\n uint32 firstSeenBlockNumber;\n //stake (first registration) block timestamp\n uint40 firstSeenTimestamp;\n bytes32[3] urlParts;\n address relayManager;\n }\n\n /**\n * @notice Emitted when a relay server registers or updates its details.\n * Looking up these events allows a client to discover registered Relay Servers.\n */\n event RelayServerRegistered(\n address indexed relayManager,\n address indexed relayHub,\n bytes32[3] relayUrl\n );\n\n /**\n * @notice This function is called by Relay Servers in order to register or to update their registration.\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\n * @param url The URL of the Relay Server that is listening to the clients' requests.\n */\n function registerRelayServer(\n address relayHub,\n bytes32[3] calldata url\n ) external;\n\n /**\n * @return The block number in which the contract has been deployed.\n */\n function getCreationBlock() external view returns (uint256);\n\n /**\n * @return The maximum age the relay is considered registered by default by this `RelayRegistrar`, in seconds.\n */\n function getRelayRegistrationMaxAge() external view returns (uint256);\n\n /**\n * @notice Change the maximum relay registration age.\n */\n function setRelayRegistrationMaxAge(uint256) external;\n\n /**\n * @param relayManager An address of a Relay Manager.\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\n * @return info All the details of the given Relay Manager's registration. Throws if relay not found for `RelayHub`.\n */\n function getRelayInfo(address relayHub, address relayManager) external view returns (RelayInfo memory info);\n\n /**\n * @notice Read relay info of registered Relay Server from an on-chain storage.\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\n * @return info The list of `RelayInfo`s of registered Relay Servers\n */\n function readRelayInfos(\n address relayHub\n ) external view returns (\n RelayInfo[] memory info\n );\n\n /**\n * @notice Read relay info of registered Relay Server from an on-chain storage.\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\n * @param maxCount The maximum amount of relays to be returned by this function.\n * @param oldestBlockNumber The latest block number in which a Relay Server may be registered.\n * @param oldestBlockTimestamp The latest block timestamp in which a Relay Server may be registered.\n * @return info The list of `RelayInfo`s of registered Relay Servers\n */\n function readRelayInfosInRange(\n address relayHub,\n uint256 oldestBlockNumber,\n uint256 oldestBlockTimestamp,\n uint256 maxCount\n ) external view returns (\n RelayInfo[] memory info\n );\n}\n" + }, + "@opengsn/contracts/src/interfaces/IStakeManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\n/**\n * @title The StakeManager Interface\n * @notice In order to prevent an attacker from registering a large number of unresponsive relays, the GSN requires\n * the Relay Server to maintain a permanently locked stake in the system before being able to register.\n *\n * @notice Also, in some cases the behavior of a Relay Server may be found to be illegal by a `Penalizer` contract.\n * In such case, the stake will never be returned to the Relay Server operator and will be slashed.\n *\n * @notice An implementation of this interface is tasked with keeping Relay Servers' stakes, made in any ERC-20 token.\n * Note that the `RelayHub` chooses which ERC-20 tokens to support and how much stake is needed.\n */\ninterface IStakeManager is IERC165 {\n\n /// @notice Emitted when a `stake` or `unstakeDelay` are initialized or increased.\n event StakeAdded(\n address indexed relayManager,\n address indexed owner,\n IERC20 token,\n uint256 stake,\n uint256 unstakeDelay\n );\n\n /// @notice Emitted once a stake is scheduled for withdrawal.\n event StakeUnlocked(\n address indexed relayManager,\n address indexed owner,\n uint256 withdrawTime\n );\n\n /// @notice Emitted when owner withdraws `relayManager` funds.\n event StakeWithdrawn(\n address indexed relayManager,\n address indexed owner,\n IERC20 token,\n uint256 amount\n );\n\n /// @notice Emitted when an authorized `RelayHub` penalizes a `relayManager`.\n event StakePenalized(\n address indexed relayManager,\n address indexed beneficiary,\n IERC20 token,\n uint256 reward\n );\n\n /// @notice Emitted when a `relayManager` adds a new `RelayHub` to a list of authorized.\n event HubAuthorized(\n address indexed relayManager,\n address indexed relayHub\n );\n\n /// @notice Emitted when a `relayManager` removes a `RelayHub` from a list of authorized.\n event HubUnauthorized(\n address indexed relayManager,\n address indexed relayHub,\n uint256 removalTime\n );\n\n /// @notice Emitted when a `relayManager` sets its `owner`. This is necessary to prevent stake hijacking.\n event OwnerSet(\n address indexed relayManager,\n address indexed owner\n );\n\n /// @notice Emitted when a `burnAddress` is changed.\n event BurnAddressSet(\n address indexed burnAddress\n );\n\n /// @notice Emitted when a `devAddress` is changed.\n event DevAddressSet(\n address indexed devAddress\n );\n\n /// @notice Emitted if Relay Server is inactive for an `abandonmentDelay` and contract owner initiates its removal.\n event RelayServerAbandoned(\n address indexed relayManager,\n uint256 abandonedTime\n );\n\n /// @notice Emitted to indicate an action performed by a relay server to prevent it from being marked as abandoned.\n event RelayServerKeepalive(\n address indexed relayManager,\n uint256 keepaliveTime\n );\n\n /// @notice Emitted when the stake of an abandoned relayer has been confiscated and transferred to the `devAddress`.\n event AbandonedRelayManagerStakeEscheated(\n address indexed relayManager,\n address indexed owner,\n IERC20 token,\n uint256 amount\n );\n\n /**\n * @param stake - amount of ether staked for this relay\n * @param unstakeDelay - number of seconds to elapse before the owner can retrieve the stake after calling 'unlock'\n * @param withdrawTime - timestamp in seconds when 'withdraw' will be callable, or zero if the unlock has not been called\n * @param owner - address that receives revenue and manages relayManager's stake\n */\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelay;\n uint256 withdrawTime;\n uint256 abandonedTime;\n uint256 keepaliveTime;\n IERC20 token;\n address owner;\n }\n\n struct RelayHubInfo {\n uint256 removalTime;\n }\n\n /**\n * @param devAddress - the address that will receive the 'abandoned' stake\n * @param abandonmentDelay - the amount of time after which the relay can be marked as 'abandoned'\n * @param escheatmentDelay - the amount of time after which the abandoned relay's stake and balance may be withdrawn to the `devAddress`\n */\n struct AbandonedRelayServerConfig {\n address devAddress;\n uint256 abandonmentDelay;\n uint256 escheatmentDelay;\n }\n\n /**\n * @notice Set the owner of a Relay Manager. Called only by the RelayManager itself.\n * Note that owners cannot transfer ownership - if the entry already exists, reverts.\n * @param owner - owner of the relay (as configured off-chain)\n */\n function setRelayManagerOwner(address owner) external;\n\n /**\n * @notice Put a stake for a relayManager and set its unstake delay.\n * Only the owner can call this function. If the entry does not exist, reverts.\n * The owner must give allowance of the ERC-20 token to the StakeManager before calling this method.\n * It is the RelayHub who has a configurable list of minimum stakes per token. StakeManager accepts all tokens.\n * @param token The address of an ERC-20 token that is used by the relayManager as a stake\n * @param relayManager The address that represents a stake entry and controls relay registrations on relay hubs\n * @param unstakeDelay The number of seconds to elapse before an owner can retrieve the stake after calling `unlock`\n * @param amount The amount of tokens to be taken from the relayOwner and locked in the StakeManager as a stake\n */\n function stakeForRelayManager(IERC20 token, address relayManager, uint256 unstakeDelay, uint256 amount) external;\n\n /**\n * @notice Schedule the unlocking of the stake. The `unstakeDelay` must pass before owner can call `withdrawStake`.\n * @param relayManager The address of a Relay Manager whose stake is to be unlocked.\n */\n function unlockStake(address relayManager) external;\n /**\n * @notice Withdraw the unlocked stake.\n * @param relayManager The address of a Relay Manager whose stake is to be withdrawn.\n */\n function withdrawStake(address relayManager) external;\n\n /**\n * @notice Add the `RelayHub` to a list of authorized by this Relay Manager.\n * This allows the RelayHub to penalize this Relay Manager. The `RelayHub` cannot trust a Relay it cannot penalize.\n * @param relayManager The address of a Relay Manager whose stake is to be authorized for the new `RelayHub`.\n * @param relayHub The address of a `RelayHub` to be authorized.\n */\n function authorizeHubByOwner(address relayManager, address relayHub) external;\n\n /**\n * @notice Same as `authorizeHubByOwner` but can be called by the RelayManager itself.\n */\n function authorizeHubByManager(address relayHub) external;\n\n /**\n * @notice Remove the `RelayHub` from a list of authorized by this Relay Manager.\n * @param relayManager The address of a Relay Manager.\n * @param relayHub The address of a `RelayHub` to be unauthorized.\n */\n function unauthorizeHubByOwner(address relayManager, address relayHub) external;\n\n /**\n * @notice Same as `unauthorizeHubByOwner` but can be called by the RelayManager itself.\n */\n function unauthorizeHubByManager(address relayHub) external;\n\n /**\n * Slash the stake of the relay relayManager. In order to prevent stake kidnapping, burns part of stake on the way.\n * @param relayManager The address of a Relay Manager to be penalized.\n * @param beneficiary The address that receives part of the penalty amount.\n * @param amount A total amount of penalty to be withdrawn from stake.\n */\n function penalizeRelayManager(address relayManager, address beneficiary, uint256 amount) external;\n\n /**\n * @notice Allows the contract owner to set the given `relayManager` as abandoned after a configurable delay.\n * Its entire stake and balance will be taken from a relay if it does not respond to being marked as abandoned.\n */\n function markRelayAbandoned(address relayManager) external;\n\n /**\n * @notice If more than `abandonmentDelay` has passed since the last Keepalive transaction, and relay manager\n * has been marked as abandoned, and after that more that `escheatmentDelay` have passed, entire stake and\n * balance will be taken from this relay.\n */\n function escheatAbandonedRelayStake(address relayManager) external;\n\n /**\n * @notice Sets a new `keepaliveTime` for the given `relayManager`, preventing it from being marked as abandoned.\n * Can be called by an authorized `RelayHub` or by the `relayOwner` address.\n */\n function updateRelayKeepaliveTime(address relayManager) external;\n\n /**\n * @notice Check if the Relay Manager can be considered abandoned or not.\n * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\n */\n function isRelayEscheatable(address relayManager) external view returns(bool);\n\n /**\n * @notice Get the stake details information for the given Relay Manager.\n * @param relayManager The address of a Relay Manager.\n * @return stakeInfo The `StakeInfo` structure.\n * @return isSenderAuthorizedHub `true` if the `msg.sender` for this call was a `RelayHub` that is authorized now.\n * `false` if the `msg.sender` for this call is not authorized.\n */\n function getStakeInfo(address relayManager) external view returns (StakeInfo memory stakeInfo, bool isSenderAuthorizedHub);\n\n /**\n * @return The maximum unstake delay this `StakeManger` allows. This is to prevent locking money forever by mistake.\n */\n function getMaxUnstakeDelay() external view returns (uint256);\n\n /**\n * @notice Change the address that will receive the 'burned' part of the penalized stake.\n * This is done to prevent malicious Relay Server from penalizing itself and breaking even.\n */\n function setBurnAddress(address _burnAddress) external;\n\n /**\n * @return The address that will receive the 'burned' part of the penalized stake.\n */\n function getBurnAddress() external view returns (address);\n\n /**\n * @notice Change the address that will receive the 'abandoned' stake.\n * This is done to prevent Relay Servers that lost their keys from losing access to funds.\n */\n function setDevAddress(address _burnAddress) external;\n\n /**\n * @return The structure that contains all configuration values for the 'abandoned' stake.\n */\n function getAbandonedRelayServerConfig() external view returns (AbandonedRelayServerConfig memory);\n\n /**\n * @return the block number in which the contract has been deployed.\n */\n function getCreationBlock() external view returns (uint256);\n\n /**\n * @return a SemVer-compliant version of the `StakeManager` contract.\n */\n function versionSM() external view returns (string memory);\n}\n" + }, + "@opengsn/contracts/src/Penalizer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\nimport \"./utils/RLPReader.sol\";\nimport \"./utils/GsnUtils.sol\";\nimport \"./interfaces/IRelayHub.sol\";\nimport \"./interfaces/IPenalizer.sol\";\n\n/**\n * @title The Penalizer Implementation\n *\n * @notice This Penalizer supports parsing Legacy, Type 1 and Type 2 raw RLP Encoded transactions.\n */\ncontract Penalizer is IPenalizer, ERC165 {\n using ECDSA for bytes32;\n\n /// @inheritdoc IPenalizer\n string public override versionPenalizer = \"3.0.0-beta.3+opengsn.penalizer.ipenalizer\";\n\n uint256 internal immutable penalizeBlockDelay;\n uint256 internal immutable penalizeBlockExpiration;\n\n constructor(\n uint256 _penalizeBlockDelay,\n uint256 _penalizeBlockExpiration\n ) {\n penalizeBlockDelay = _penalizeBlockDelay;\n penalizeBlockExpiration = _penalizeBlockExpiration;\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n return interfaceId == type(IPenalizer).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IPenalizer\n function getPenalizeBlockDelay() external override view returns (uint256) {\n return penalizeBlockDelay;\n }\n\n /// @inheritdoc IPenalizer\n function getPenalizeBlockExpiration() external override view returns (uint256) {\n return penalizeBlockExpiration;\n }\n\n function isLegacyTransaction(bytes calldata rawTransaction) internal pure returns (bool) {\n uint8 transactionTypeByte = uint8(rawTransaction[0]);\n return (transactionTypeByte >= 0xc0 && transactionTypeByte <= 0xfe);\n }\n\n function isTransactionType1(bytes calldata rawTransaction) internal pure returns (bool) {\n return (uint8(rawTransaction[0]) == 1);\n }\n\n function isTransactionType2(bytes calldata rawTransaction) internal pure returns (bool) {\n return (uint8(rawTransaction[0]) == 2);\n }\n\n /// @return `true` if raw transaction is of types Legacy, 1 or 2. `false` otherwise.\n function isTransactionTypeValid(bytes calldata rawTransaction) public pure returns(bool) {\n return isLegacyTransaction(rawTransaction) || isTransactionType1(rawTransaction) || isTransactionType2(rawTransaction);\n }\n\n /// @return transaction The details that the `Penalizer` needs to decide if the transaction is penalizable.\n function decodeTransaction(bytes calldata rawTransaction) public pure returns (Transaction memory transaction) {\n if (isTransactionType1(rawTransaction)) {\n (transaction.nonce,\n transaction.gasLimit,\n transaction.to,\n transaction.value,\n transaction.data) = RLPReader.decodeTransactionType1(rawTransaction);\n } else if (isTransactionType2(rawTransaction)) {\n (transaction.nonce,\n transaction.gasLimit,\n transaction.to,\n transaction.value,\n transaction.data) = RLPReader.decodeTransactionType2(rawTransaction);\n } else {\n (transaction.nonce,\n transaction.gasLimit,\n transaction.to,\n transaction.value,\n transaction.data) = RLPReader.decodeLegacyTransaction(rawTransaction);\n }\n return transaction;\n }\n\n mapping(bytes32 => uint256) public commits;\n\n /// @inheritdoc IPenalizer\n function commit(bytes32 commitHash) external override {\n uint256 readyBlockNumber = block.number + penalizeBlockDelay;\n commits[commitHash] = readyBlockNumber;\n emit CommitAdded(msg.sender, commitHash, readyBlockNumber);\n }\n\n /// Modifier that verifies there was a `commit` operation before this call that has not expired yet.\n modifier commitRevealOnly() {\n bytes32 commitHash = keccak256(abi.encodePacked(keccak256(msg.data), msg.sender));\n uint256 readyBlockNumber = commits[commitHash];\n delete commits[commitHash];\n // msg.sender can only be fake during off-chain view call, allowing Penalizer process to check transactions\n if(msg.sender != address(type(uint160).max)) {\n require(readyBlockNumber != 0, \"no commit\");\n require(readyBlockNumber < block.number, \"reveal penalize too soon\");\n require(readyBlockNumber + penalizeBlockExpiration > block.number, \"reveal penalize too late\");\n }\n _;\n }\n\n /// @inheritdoc IPenalizer\n function penalizeRepeatedNonce(\n bytes calldata unsignedTx1,\n bytes calldata signature1,\n bytes calldata unsignedTx2,\n bytes calldata signature2,\n IRelayHub hub,\n uint256 randomValue\n )\n public\n override\n commitRevealOnly {\n (randomValue);\n _penalizeRepeatedNonce(unsignedTx1, signature1, unsignedTx2, signature2, hub);\n }\n\n function _penalizeRepeatedNonce(\n bytes calldata unsignedTx1,\n bytes calldata signature1,\n bytes calldata unsignedTx2,\n bytes calldata signature2,\n IRelayHub hub\n )\n private\n {\n address addr1 = keccak256(unsignedTx1).recover(signature1);\n address addr2 = keccak256(unsignedTx2).recover(signature2);\n\n require(addr1 == addr2, \"Different signer\");\n require(addr1 != address(0), \"ecrecover failed\");\n\n Transaction memory decodedTx1 = decodeTransaction(unsignedTx1);\n Transaction memory decodedTx2 = decodeTransaction(unsignedTx2);\n\n // checking that the same nonce is used in both transaction, with both signed by the same address\n // and the actual data is different\n // note: we compare the hash of the tx to save gas over iterating both byte arrays\n require(decodedTx1.nonce == decodedTx2.nonce, \"Different nonce\");\n\n bytes memory dataToCheck1 =\n abi.encodePacked(decodedTx1.data, decodedTx1.gasLimit, decodedTx1.to, decodedTx1.value);\n\n bytes memory dataToCheck2 =\n abi.encodePacked(decodedTx2.data, decodedTx2.gasLimit, decodedTx2.to, decodedTx2.value);\n\n require(keccak256(dataToCheck1) != keccak256(dataToCheck2), \"tx is equal\");\n\n penalize(addr1, hub);\n }\n\n /// @inheritdoc IPenalizer\n function penalizeIllegalTransaction(\n bytes calldata unsignedTx,\n bytes calldata signature,\n IRelayHub hub,\n uint256 randomValue\n )\n public\n override\n commitRevealOnly {\n (randomValue);\n _penalizeIllegalTransaction(unsignedTx, signature, hub);\n }\n\n function _penalizeIllegalTransaction(\n bytes calldata unsignedTx,\n bytes calldata signature,\n IRelayHub hub\n )\n private\n {\n if (isTransactionTypeValid(unsignedTx)) {\n Transaction memory decodedTx = decodeTransaction(unsignedTx);\n if (decodedTx.to == address(hub)) {\n bytes4 selector = GsnUtils.getMethodSig(decodedTx.data);\n bool isWrongMethodCall = selector != IRelayHub.relayCall.selector;\n require(\n isWrongMethodCall,\n \"Legal relay transaction\");\n }\n }\n address relay = keccak256(unsignedTx).recover(signature);\n require(relay != address(0), \"ecrecover failed\");\n penalize(relay, hub);\n }\n\n function penalize(address relayWorker, IRelayHub hub) private {\n hub.penalize(relayWorker, payable(msg.sender));\n }\n}\n" + }, + "@opengsn/contracts/src/RelayHub.sol": { + "content": "/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable not-rely-on-time */\n/* solhint-disable avoid-tx-origin */\n/* solhint-disable bracket-align */\n// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\npragma abicoder v2;\n\n// #if ENABLE_CONSOLE_LOG\nimport \"hardhat/console.sol\";\n// #endif\n\nimport \"./utils/MinLibBytes.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"./utils/GsnUtils.sol\";\nimport \"./utils/GsnEip712Library.sol\";\nimport \"./utils/RelayHubValidator.sol\";\nimport \"./utils/GsnTypes.sol\";\nimport \"./interfaces/IRelayHub.sol\";\nimport \"./interfaces/IPaymaster.sol\";\nimport \"./forwarder/IForwarder.sol\";\nimport \"./interfaces/IStakeManager.sol\";\nimport \"./interfaces/IRelayRegistrar.sol\";\nimport \"./interfaces/IStakeManager.sol\";\n\n/**\n * @title The RelayHub Implementation\n * @notice This contract implements the `IRelayHub` interface for the EVM-compatible networks.\n */\ncontract RelayHub is IRelayHub, Ownable, ERC165 {\n using ERC165Checker for address;\n using Address for address;\n\n address private constant DRY_RUN_ADDRESS = 0x0000000000000000000000000000000000000000;\n\n /// @inheritdoc IRelayHub\n function versionHub() override virtual public pure returns (string memory){\n return \"3.0.0-beta.3+opengsn.hub.irelayhub\";\n }\n\n IStakeManager internal immutable stakeManager;\n address internal immutable penalizer;\n address internal immutable batchGateway;\n address internal immutable relayRegistrar;\n\n RelayHubConfig internal config;\n\n /// @inheritdoc IRelayHub\n function getConfiguration() public override view returns (RelayHubConfig memory) {\n return config;\n }\n\n /// @inheritdoc IRelayHub\n function setConfiguration(RelayHubConfig memory _config) public override onlyOwner {\n require(_config.devFee < 100, \"dev fee too high\");\n config = _config;\n emit RelayHubConfigured(config);\n }\n\n // maps ERC-20 token address to a minimum stake for it\n mapping(IERC20 => uint256) internal minimumStakePerToken;\n\n /// @inheritdoc IRelayHub\n function setMinimumStakes(IERC20[] memory token, uint256[] memory minimumStake) public override onlyOwner {\n require(token.length == minimumStake.length, \"setMinimumStakes: wrong length\");\n for (uint256 i = 0; i < token.length; i++) {\n minimumStakePerToken[token[i]] = minimumStake[i];\n emit StakingTokenDataChanged(address(token[i]), minimumStake[i]);\n }\n }\n\n // maps relay worker's address to its manager's address\n mapping(address => address) internal workerToManager;\n\n // maps relay managers to the number of their workers\n mapping(address => uint256) internal workerCount;\n\n mapping(address => uint256) internal balances;\n\n uint256 internal immutable creationBlock;\n uint256 internal deprecationTime = type(uint256).max;\n\n constructor (\n IStakeManager _stakeManager,\n address _penalizer,\n address _batchGateway,\n address _relayRegistrar,\n RelayHubConfig memory _config\n ) {\n creationBlock = block.number;\n stakeManager = _stakeManager;\n penalizer = _penalizer;\n batchGateway = _batchGateway;\n relayRegistrar = _relayRegistrar;\n setConfiguration(_config);\n }\n\n /// @inheritdoc IRelayHub\n function getCreationBlock() external override virtual view returns (uint256){\n return creationBlock;\n }\n\n /// @inheritdoc IRelayHub\n function getDeprecationTime() external override view returns (uint256) {\n return deprecationTime;\n }\n\n /// @inheritdoc IRelayHub\n function getStakeManager() external override view returns (IStakeManager) {\n return stakeManager;\n }\n\n /// @inheritdoc IRelayHub\n function getPenalizer() external override view returns (address) {\n return penalizer;\n }\n\n /// @inheritdoc IRelayHub\n function getBatchGateway() external override view returns (address) {\n return batchGateway;\n }\n\n /// @inheritdoc IRelayHub\n function getRelayRegistrar() external override view returns (address) {\n return relayRegistrar;\n }\n\n /// @inheritdoc IRelayHub\n function getMinimumStakePerToken(IERC20 token) external override view returns (uint256) {\n return minimumStakePerToken[token];\n }\n\n /// @inheritdoc IRelayHub\n function getWorkerManager(address worker) external override view returns (address) {\n return workerToManager[worker];\n }\n\n /// @inheritdoc IRelayHub\n function getWorkerCount(address manager) external override view returns (uint256) {\n return workerCount[manager];\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n return interfaceId == type(IRelayHub).interfaceId ||\n interfaceId == type(Ownable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IRelayHub\n function onRelayServerRegistered(address relayManager) external override {\n require(msg.sender == relayRegistrar, \"caller is not relay registrar\");\n verifyRelayManagerStaked(relayManager);\n require(workerCount[relayManager] > 0, \"no relay workers\");\n stakeManager.updateRelayKeepaliveTime(relayManager);\n }\n\n /// @inheritdoc IRelayHub\n function addRelayWorkers(address[] calldata newRelayWorkers) external override {\n address relayManager = msg.sender;\n uint256 newWorkerCount = workerCount[relayManager] + newRelayWorkers.length;\n workerCount[relayManager] = newWorkerCount;\n require(newWorkerCount <= config.maxWorkerCount, \"too many workers\");\n\n verifyRelayManagerStaked(relayManager);\n\n for (uint256 i = 0; i < newRelayWorkers.length; i++) {\n require(workerToManager[newRelayWorkers[i]] == address(0), \"this worker has a manager\");\n workerToManager[newRelayWorkers[i]] = relayManager;\n }\n\n emit RelayWorkersAdded(relayManager, newRelayWorkers, newWorkerCount);\n }\n\n /// @inheritdoc IRelayHub\n function depositFor(address target) public virtual override payable {\n require(target.supportsInterface(type(IPaymaster).interfaceId), \"target is not a valid IPaymaster\");\n uint256 amount = msg.value;\n\n balances[target] = balances[target] + amount;\n\n emit Deposited(target, msg.sender, amount);\n }\n\n /// @inheritdoc IRelayHub\n function balanceOf(address target) external override view returns (uint256) {\n return balances[target];\n }\n\n /// @inheritdoc IRelayHub\n function withdraw(address payable dest, uint256 amount) public override {\n uint256[] memory amounts = new uint256[](1);\n address payable[] memory destinations = new address payable[](1);\n amounts[0] = amount;\n destinations[0] = dest;\n withdrawMultiple(destinations, amounts);\n }\n\n /// @inheritdoc IRelayHub\n function withdrawMultiple(address payable[] memory dest, uint256[] memory amount) public override {\n address payable account = payable(msg.sender);\n for (uint256 i = 0; i < amount.length; i++) {\n // #if ENABLE_CONSOLE_LOG\n console.log(\"withdrawMultiple %s %s %s\", balances[account], dest[i], amount[i]);\n // #endif\n uint256 balance = balances[account];\n require(balance >= amount[i], \"insufficient funds\");\n balances[account] = balance - amount[i];\n (bool success, ) = dest[i].call{value: amount[i]}(\"\");\n require(success, \"Transfer failed.\");\n emit Withdrawn(account, dest[i], amount[i]);\n }\n }\n\n function verifyGasAndDataLimits(\n uint256 maxAcceptanceBudget,\n GsnTypes.RelayRequest calldata relayRequest,\n uint256 initialGasLeft\n )\n private\n view\n returns (IPaymaster.GasAndDataLimits memory gasAndDataLimits, uint256 maxPossibleGas) {\n gasAndDataLimits =\n IPaymaster(relayRequest.relayData.paymaster).getGasAndDataLimits{gas:50000}();\n require(msg.data.length <= gasAndDataLimits.calldataSizeLimit, \"msg.data exceeded limit\" );\n\n require(maxAcceptanceBudget >= gasAndDataLimits.acceptanceBudget, \"acceptance budget too high\");\n require(gasAndDataLimits.acceptanceBudget >= gasAndDataLimits.preRelayedCallGasLimit, \"acceptance budget too low\");\n\n maxPossibleGas = relayRequest.relayData.transactionCalldataGasUsed + initialGasLeft;\n\n uint256 maxPossibleCharge = calculateCharge(\n maxPossibleGas,\n relayRequest.relayData\n );\n\n // We don't yet know how much gas will be used by the recipient, so we make sure there are enough funds to pay\n // for the maximum possible charge.\n require(maxPossibleCharge <= balances[relayRequest.relayData.paymaster],\n \"Paymaster balance too low\");\n }\n\n struct RelayCallData {\n bool success;\n bytes4 functionSelector;\n uint256 initialGasLeft;\n bytes recipientContext;\n bytes relayedCallReturnValue;\n IPaymaster.GasAndDataLimits gasAndDataLimits;\n RelayCallStatus status;\n uint256 innerGasUsed;\n uint256 maxPossibleGas;\n uint256 innerGasLimit;\n uint256 gasBeforeInner;\n uint256 gasUsed;\n uint256 devCharge;\n bytes retData;\n address relayManager;\n bytes32 relayRequestId;\n uint256 tmpInitialGas;\n bytes relayCallStatus;\n }\n\n /// @inheritdoc IRelayHub\n function relayCall(\n string calldata domainSeparatorName,\n uint256 maxAcceptanceBudget,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData\n )\n external\n override\n returns (\n bool paymasterAccepted,\n uint256 charge,\n IRelayHub.RelayCallStatus status,\n bytes memory returnValue)\n {\n RelayCallData memory vars;\n vars.initialGasLeft = aggregateGasleft();\n vars.relayRequestId = GsnUtils.getRelayRequestID(relayRequest, signature);\n\n // #if ENABLE_CONSOLE_LOG\n console.log(\"relayCall relayRequestId\");\n console.logBytes32(vars.relayRequestId);\n console.log(\"relayCall relayRequest.request.from\", relayRequest.request.from);\n console.log(\"relayCall relayRequest.request.to\", relayRequest.request.to);\n console.log(\"relayCall relayRequest.request.value\", relayRequest.request.value);\n console.log(\"relayCall relayRequest.request.gas\", relayRequest.request.gas);\n console.log(\"relayCall relayRequest.request.nonce\", relayRequest.request.nonce);\n console.log(\"relayCall relayRequest.request.validUntilTime\", relayRequest.request.validUntilTime);\n\n console.log(\"relayCall relayRequest.relayData.maxFeePerGas\", relayRequest.relayData.maxFeePerGas);\n console.log(\"relayCall relayRequest.relayData.maxPriorityFeePerGas\", relayRequest.relayData.maxPriorityFeePerGas);\n console.log(\"relayCall relayRequest.relayData.transactionCalldataGasUsed\", relayRequest.relayData.transactionCalldataGasUsed);\n console.log(\"relayCall relayRequest.relayData.relayWorker\", relayRequest.relayData.relayWorker);\n console.log(\"relayCall relayRequest.relayData.paymaster\", relayRequest.relayData.paymaster);\n console.log(\"relayCall relayRequest.relayData.forwarder\", relayRequest.relayData.forwarder);\n console.log(\"relayCall relayRequest.relayData.clientId\", relayRequest.relayData.clientId);\n\n console.log(\"relayCall domainSeparatorName\");\n console.logString(domainSeparatorName);\n console.log(\"relayCall signature\");\n console.logBytes(signature);\n console.log(\"relayCall approvalData\");\n console.logBytes(approvalData);\n console.log(\"relayCall relayRequest.request.data\");\n console.logBytes(relayRequest.request.data);\n console.log(\"relayCall relayRequest.relayData.paymasterData\");\n console.logBytes(relayRequest.relayData.paymasterData);\n console.log(\"relayCall maxAcceptanceBudget\", maxAcceptanceBudget);\n // #endif\n\n require(!isDeprecated(), \"hub deprecated\");\n vars.functionSelector = relayRequest.request.data.length>=4 ? MinLibBytes.readBytes4(relayRequest.request.data, 0) : bytes4(0);\n\n if (msg.sender != batchGateway && tx.origin != DRY_RUN_ADDRESS) {\n require(signature.length != 0, \"missing signature or bad gateway\");\n require(msg.sender == tx.origin, \"relay worker must be EOA\");\n require(msg.sender == relayRequest.relayData.relayWorker, \"Not a right worker\");\n }\n\n if (tx.origin != DRY_RUN_ADDRESS) {\n vars.relayManager = workerToManager[relayRequest.relayData.relayWorker];\n require(vars.relayManager != address(0), \"Unknown relay worker\");\n verifyRelayManagerStaked(vars.relayManager);\n }\n\n (vars.gasAndDataLimits, vars.maxPossibleGas) =\n verifyGasAndDataLimits(maxAcceptanceBudget, relayRequest, vars.initialGasLeft);\n\n RelayHubValidator.verifyTransactionPacking(domainSeparatorName,relayRequest,signature,approvalData);\n\n {\n\n //How much gas to pass down to innerRelayCall. must be lower than the default 63/64\n // actually, min(gasleft*63/64, gasleft-GAS_RESERVE) might be enough.\n vars.innerGasLimit = gasleft()*63/64- config.gasReserve;\n vars.gasBeforeInner = aggregateGasleft();\n\n /*\n Preparing to calculate \"gasUseWithoutPost\":\n MPG = calldataGasUsage + vars.initialGasLeft :: max possible gas, an approximate gas limit for the current transaction\n GU1 = MPG - gasleft(called right before innerRelayCall) :: gas actually used by current transaction until that point\n GU2 = innerGasLimit - gasleft(called inside the innerRelayCall just before preRelayedCall) :: gas actually used by innerRelayCall before calling postRelayCall\n GWP1 = GU1 + GU2 :: gas actually used by the entire transaction before calling postRelayCall\n TGO = config.gasOverhead + config.postOverhead :: extra that will be added to the charge to cover hidden costs\n GWP = GWP1 + TGO :: transaction \"gas used without postRelayCall\"\n */\n vars.tmpInitialGas = relayRequest.relayData.transactionCalldataGasUsed + vars.initialGasLeft + vars.innerGasLimit + config.gasOverhead + config.postOverhead;\n // Calls to the recipient are performed atomically inside an inner transaction which may revert in case of\n // errors in the recipient. In either case (revert or regular execution) the return data encodes the\n // RelayCallStatus value.\n (vars.success, vars.relayCallStatus) = address(this).call{gas:vars.innerGasLimit}(\n abi.encodeWithSelector(RelayHub.innerRelayCall.selector, domainSeparatorName, relayRequest, signature, approvalData, vars.gasAndDataLimits,\n vars.tmpInitialGas - aggregateGasleft(), /* totalInitialGas */\n vars.maxPossibleGas\n )\n );\n vars.innerGasUsed = vars.gasBeforeInner-aggregateGasleft();\n (vars.status, vars.relayedCallReturnValue) = abi.decode(vars.relayCallStatus, (RelayCallStatus, bytes));\n if ( vars.relayedCallReturnValue.length>0 ) {\n emit TransactionResult(vars.status, vars.relayedCallReturnValue);\n }\n }\n {\n if (!vars.success) {\n //Failure cases where the PM doesn't pay\n if (vars.status == RelayCallStatus.RejectedByPreRelayed ||\n (vars.innerGasUsed <= vars.gasAndDataLimits.acceptanceBudget + relayRequest.relayData.transactionCalldataGasUsed) && (\n vars.status == RelayCallStatus.RejectedByForwarder ||\n vars.status == RelayCallStatus.RejectedByRecipientRevert //can only be thrown if rejectOnRecipientRevert==true\n )) {\n emit TransactionRejectedByPaymaster(\n vars.relayManager,\n relayRequest.relayData.paymaster,\n vars.relayRequestId,\n relayRequest.request.from,\n relayRequest.request.to,\n msg.sender,\n vars.functionSelector,\n vars.innerGasUsed,\n vars.relayedCallReturnValue);\n return (false, 0, vars.status, vars.relayedCallReturnValue);\n }\n }\n\n // We now perform the actual charge calculation, based on the measured gas used\n vars.gasUsed = relayRequest.relayData.transactionCalldataGasUsed + (vars.initialGasLeft - aggregateGasleft()) + config.gasOverhead;\n charge = calculateCharge(vars.gasUsed, relayRequest.relayData);\n vars.devCharge = calculateDevCharge(charge);\n\n balances[relayRequest.relayData.paymaster] = balances[relayRequest.relayData.paymaster] - charge;\n balances[vars.relayManager] = balances[vars.relayManager] + (charge - vars.devCharge);\n if (vars.devCharge > 0) { // save some gas in case of zero dev charge\n balances[config.devAddress] = balances[config.devAddress] + vars.devCharge;\n }\n\n {\n address from = relayRequest.request.from;\n address to = relayRequest.request.to;\n address paymaster = relayRequest.relayData.paymaster;\n emit TransactionRelayed(\n vars.relayManager,\n msg.sender,\n vars.relayRequestId,\n from,\n to,\n paymaster,\n vars.functionSelector,\n vars.status,\n charge);\n }\n\n // avoid variable size memory copying after gas calculation completed on-chain\n if (tx.origin == DRY_RUN_ADDRESS) {\n return (true, charge, vars.status, vars.relayedCallReturnValue);\n }\n return (true, charge, vars.status, \"\");\n }\n }\n\n struct InnerRelayCallData {\n uint256 initialGasLeft;\n uint256 gasUsedToCallInner;\n uint256 balanceBefore;\n bytes32 preReturnValue;\n bool relayedCallSuccess;\n bytes relayedCallReturnValue;\n bytes recipientContext;\n bytes data;\n bool rejectOnRecipientRevert;\n }\n\n /**\n * @notice This method can only by called by this `RelayHub`.\n * It wraps the execution of the `RelayRequest` in a revertable frame context.\n */\n function innerRelayCall(\n string calldata domainSeparatorName,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n IPaymaster.GasAndDataLimits calldata gasAndDataLimits,\n uint256 totalInitialGas,\n uint256 maxPossibleGas\n )\n external\n returns (RelayCallStatus, bytes memory)\n {\n InnerRelayCallData memory vars;\n vars.initialGasLeft = aggregateGasleft();\n vars.gasUsedToCallInner = totalInitialGas - gasleft();\n // A new gas measurement is performed inside innerRelayCall, since\n // due to EIP150 available gas amounts cannot be directly compared across external calls\n\n // This external function can only be called by RelayHub itself, creating an internal transaction. Calls to the\n // recipient (preRelayedCall, the relayedCall, and postRelayedCall) are called from inside this transaction.\n require(msg.sender == address(this), \"Must be called by RelayHub\");\n\n // If either pre or post reverts, the whole internal transaction will be reverted, reverting all side effects on\n // the recipient. The recipient will still be charged for the used gas by the relay.\n\n // The paymaster is no allowed to withdraw balance from RelayHub during a relayed transaction. We check pre and\n // post state to ensure this doesn't happen.\n vars.balanceBefore = balances[relayRequest.relayData.paymaster];\n\n // First preRelayedCall is executed.\n // Note: we open a new block to avoid growing the stack too much.\n vars.data = abi.encodeWithSelector(\n IPaymaster.preRelayedCall.selector,\n relayRequest, signature, approvalData, maxPossibleGas\n );\n {\n bool success;\n bytes memory retData;\n (success, retData) = relayRequest.relayData.paymaster.call{gas:gasAndDataLimits.preRelayedCallGasLimit}(vars.data);\n if (!success) {\n GsnEip712Library.truncateInPlace(retData);\n revertWithStatus(RelayCallStatus.RejectedByPreRelayed, retData);\n }\n (vars.recipientContext, vars.rejectOnRecipientRevert) = abi.decode(retData, (bytes,bool));\n }\n\n // The actual relayed call is now executed. The sender's address is appended at the end of the transaction data\n\n {\n bool forwarderSuccess;\n (forwarderSuccess, vars.relayedCallSuccess, vars.relayedCallReturnValue) = GsnEip712Library.execute(domainSeparatorName, relayRequest, signature);\n if ( !forwarderSuccess ) {\n revertWithStatus(RelayCallStatus.RejectedByForwarder, vars.relayedCallReturnValue);\n }\n\n if (vars.rejectOnRecipientRevert && !vars.relayedCallSuccess) {\n // we trusted the recipient, but it reverted...\n revertWithStatus(RelayCallStatus.RejectedByRecipientRevert, vars.relayedCallReturnValue);\n }\n }\n // Finally, postRelayedCall is executed, with the relayedCall execution's status and a charge estimate\n // We now determine how much the recipient will be charged, to pass this value to postRelayedCall for accurate\n // accounting.\n vars.data = abi.encodeWithSelector(\n IPaymaster.postRelayedCall.selector,\n vars.recipientContext,\n vars.relayedCallSuccess,\n vars.gasUsedToCallInner + (vars.initialGasLeft - aggregateGasleft()), /*gasUseWithoutPost*/\n relayRequest.relayData\n );\n\n {\n (bool successPost,bytes memory ret) = relayRequest.relayData.paymaster.call{gas:gasAndDataLimits.postRelayedCallGasLimit}(vars.data);\n\n if (!successPost) {\n revertWithStatus(RelayCallStatus.PostRelayedFailed, ret);\n }\n }\n\n if (balances[relayRequest.relayData.paymaster] < vars.balanceBefore) {\n revertWithStatus(RelayCallStatus.PaymasterBalanceChanged, \"\");\n }\n\n return (vars.relayedCallSuccess ? RelayCallStatus.OK : RelayCallStatus.RelayedCallFailed, vars.relayedCallReturnValue);\n }\n\n /**\n * @dev Reverts the transaction with return data set to the ABI encoding of the status argument (and revert reason data)\n */\n function revertWithStatus(RelayCallStatus status, bytes memory ret) private pure {\n bytes memory data = abi.encode(status, ret);\n GsnEip712Library.truncateInPlace(data);\n\n assembly {\n let dataSize := mload(data)\n let dataPtr := add(data, 32)\n\n revert(dataPtr, dataSize)\n }\n }\n\n /// @inheritdoc IRelayHub\n function calculateDevCharge(uint256 charge) public override virtual view returns (uint256){\n if (config.devFee == 0){ // save some gas in case of zero dev charge\n return 0;\n }\n unchecked {\n return charge * config.devFee / 100;\n }\n }\n\n /// @inheritdoc IRelayHub\n function calculateCharge(uint256 gasUsed, GsnTypes.RelayData calldata relayData) public override virtual view returns (uint256) {\n uint256 basefee;\n if (relayData.maxFeePerGas == relayData.maxPriorityFeePerGas) {\n basefee = 0;\n } else {\n basefee = block.basefee;\n }\n uint256 chargeableGasPrice = Math.min(relayData.maxFeePerGas, Math.min(tx.gasprice, basefee + relayData.maxPriorityFeePerGas));\n return config.baseRelayFee + (gasUsed * chargeableGasPrice * (config.pctRelayFee + 100)) / 100;\n }\n\n /// @inheritdoc IRelayHub\n function verifyRelayManagerStaked(address relayManager) public override view {\n (IStakeManager.StakeInfo memory info, bool isHubAuthorized) = stakeManager.getStakeInfo(relayManager);\n uint256 minimumStake = minimumStakePerToken[info.token];\n require(info.token != IERC20(address(0)), \"relay manager not staked\");\n require(info.stake >= minimumStake, \"stake amount is too small\");\n require(minimumStake != 0, \"staking this token is forbidden\");\n require(info.unstakeDelay >= config.minimumUnstakeDelay, \"unstake delay is too small\");\n require(info.withdrawTime == 0, \"stake has been withdrawn\");\n require(isHubAuthorized, \"this hub is not authorized by SM\");\n }\n\n /// @inheritdoc IRelayHub\n function deprecateHub(uint256 _deprecationTime) public override onlyOwner {\n require(!isDeprecated(), \"Already deprecated\");\n deprecationTime = _deprecationTime;\n emit HubDeprecated(deprecationTime);\n }\n\n /// @inheritdoc IRelayHub\n function isDeprecated() public override view returns (bool) {\n return block.timestamp >= deprecationTime;\n }\n\n /// @notice Prevents any address other than the `Penalizer` from calling this method.\n modifier penalizerOnly () {\n require(msg.sender == penalizer, \"Not penalizer\");\n _;\n }\n\n /// @inheritdoc IRelayHub\n function penalize(address relayWorker, address payable beneficiary) external override penalizerOnly {\n address relayManager = workerToManager[relayWorker];\n // The worker must be controlled by a manager with a locked stake\n require(relayManager != address(0), \"Unknown relay worker\");\n (IStakeManager.StakeInfo memory stakeInfo,) = stakeManager.getStakeInfo(relayManager);\n require(stakeInfo.stake > 0, \"relay manager not staked\");\n stakeManager.penalizeRelayManager(relayManager, beneficiary, stakeInfo.stake);\n }\n\n /// @inheritdoc IRelayHub\n function isRelayEscheatable(address relayManager) public view override returns (bool){\n return stakeManager.isRelayEscheatable(relayManager);\n }\n\n /// @inheritdoc IRelayHub\n function escheatAbandonedRelayBalance(address relayManager) external override onlyOwner {\n require(stakeManager.isRelayEscheatable(relayManager), \"relay server not escheatable yet\");\n uint256 balance = balances[relayManager];\n balances[relayManager] = 0;\n balances[config.devAddress] = balances[config.devAddress] + balance;\n emit AbandonedRelayManagerBalanceEscheated(relayManager, balance);\n }\n\n /// @inheritdoc IRelayHub\n function aggregateGasleft() public override virtual view returns (uint256){\n return gasleft();\n }\n}\n" + }, + "@opengsn/contracts/src/StakeManager.sol": { + "content": "// solhint-disable not-rely-on-time\n// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\nimport \"./interfaces/IStakeManager.sol\";\n\n/**\n * @title The StakeManager implementation\n * @notice An IStakeManager instance that accepts stakes in any ERC-20 token.\n *\n * @notice Single StakeInfo of a single RelayManager can only have one token address assigned to it.\n *\n * @notice It cannot be changed after the first time 'stakeForRelayManager' is called as it is equivalent to withdrawal.\n */\ncontract StakeManager is IStakeManager, Ownable, ERC165 {\n using SafeERC20 for IERC20;\n\n string public override versionSM = \"3.0.0-beta.3+opengsn.stakemanager.istakemanager\";\n uint256 internal immutable maxUnstakeDelay;\n\n AbandonedRelayServerConfig internal abandonedRelayServerConfig;\n\n address internal burnAddress;\n uint256 internal immutable creationBlock;\n\n /// maps relay managers to their stakes\n mapping(address => StakeInfo) public stakes;\n\n /// @inheritdoc IStakeManager\n function getStakeInfo(address relayManager) external override view returns (StakeInfo memory stakeInfo, bool isSenderAuthorizedHub) {\n bool isHubAuthorized = authorizedHubs[relayManager][msg.sender].removalTime == type(uint256).max;\n return (stakes[relayManager], isHubAuthorized);\n }\n\n /// @inheritdoc IStakeManager\n function setBurnAddress(address _burnAddress) public override onlyOwner {\n burnAddress = _burnAddress;\n emit BurnAddressSet(burnAddress);\n }\n\n /// @inheritdoc IStakeManager\n function getBurnAddress() external override view returns (address) {\n return burnAddress;\n }\n\n /// @inheritdoc IStakeManager\n function setDevAddress(address _devAddress) public override onlyOwner {\n abandonedRelayServerConfig.devAddress = _devAddress;\n emit DevAddressSet(abandonedRelayServerConfig.devAddress);\n }\n\n /// @inheritdoc IStakeManager\n function getAbandonedRelayServerConfig() external override view returns (AbandonedRelayServerConfig memory) {\n return abandonedRelayServerConfig;\n }\n\n /// @inheritdoc IStakeManager\n function getMaxUnstakeDelay() external override view returns (uint256) {\n return maxUnstakeDelay;\n }\n\n /// maps relay managers to a map of addressed of their authorized hubs to the information on that hub\n mapping(address => mapping(address => RelayHubInfo)) public authorizedHubs;\n\n constructor(\n uint256 _maxUnstakeDelay,\n uint256 _abandonmentDelay,\n uint256 _escheatmentDelay,\n address _burnAddress,\n address _devAddress\n ) {\n require(_burnAddress != address(0), \"transfers to address(0) may fail\");\n setBurnAddress(_burnAddress);\n setDevAddress(_devAddress);\n creationBlock = block.number;\n maxUnstakeDelay = _maxUnstakeDelay;\n abandonedRelayServerConfig.abandonmentDelay = _abandonmentDelay;\n abandonedRelayServerConfig.escheatmentDelay = _escheatmentDelay;\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n return interfaceId == type(IStakeManager).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IStakeManager\n function getCreationBlock() external override view returns (uint256){\n return creationBlock;\n }\n\n /// @inheritdoc IStakeManager\n function setRelayManagerOwner(address owner) external override {\n require(owner != address(0), \"invalid owner\");\n require(stakes[msg.sender].owner == address(0), \"already owned\");\n stakes[msg.sender].owner = owner;\n emit OwnerSet(msg.sender, owner);\n }\n\n /// @inheritdoc IStakeManager\n function stakeForRelayManager(IERC20 token, address relayManager, uint256 unstakeDelay, uint256 amount) external override relayOwnerOnly(relayManager) {\n require(unstakeDelay >= stakes[relayManager].unstakeDelay, \"unstakeDelay cannot be decreased\");\n require(unstakeDelay <= maxUnstakeDelay, \"unstakeDelay too big\");\n require(token != IERC20(address(0)), \"must specify stake token address\");\n require(\n stakes[relayManager].token == IERC20(address(0)) ||\n stakes[relayManager].token == token,\n \"stake token address is incorrect\");\n token.safeTransferFrom(msg.sender, address(this), amount);\n stakes[relayManager].token = token;\n stakes[relayManager].stake += amount;\n stakes[relayManager].unstakeDelay = unstakeDelay;\n emit StakeAdded(relayManager, stakes[relayManager].owner, stakes[relayManager].token, stakes[relayManager].stake, stakes[relayManager].unstakeDelay);\n }\n\n /// @inheritdoc IStakeManager\n function unlockStake(address relayManager) external override relayOwnerOnly(relayManager) {\n StakeInfo storage info = stakes[relayManager];\n require(info.withdrawTime == 0, \"already pending\");\n info.withdrawTime = block.timestamp + info.unstakeDelay;\n emit StakeUnlocked(relayManager, msg.sender, info.withdrawTime);\n }\n\n /// @inheritdoc IStakeManager\n function withdrawStake(address relayManager) external override relayOwnerOnly(relayManager) {\n StakeInfo storage info = stakes[relayManager];\n require(info.withdrawTime > 0, \"Withdrawal is not scheduled\");\n require(info.withdrawTime <= block.timestamp, \"Withdrawal is not due\");\n uint256 amount = info.stake;\n info.stake = 0;\n info.withdrawTime = 0;\n info.token.safeTransfer(msg.sender, amount);\n emit StakeWithdrawn(relayManager, msg.sender, info.token, amount);\n }\n\n /// @notice Prevents any address other than a registered Relay Owner from calling this method.\n modifier relayOwnerOnly (address relayManager) {\n StakeInfo storage info = stakes[relayManager];\n require(info.owner == msg.sender, \"not owner\");\n _;\n }\n\n /// @notice Prevents any address other than a registered Relay Manager from calling this method.\n modifier managerOnly () {\n StakeInfo storage info = stakes[msg.sender];\n require(info.owner != address(0), \"not manager\");\n _;\n }\n\n /// @inheritdoc IStakeManager\n function authorizeHubByOwner(address relayManager, address relayHub) external relayOwnerOnly(relayManager) override {\n _authorizeHub(relayManager, relayHub);\n }\n\n /// @inheritdoc IStakeManager\n function authorizeHubByManager(address relayHub) external managerOnly override {\n _authorizeHub(msg.sender, relayHub);\n }\n\n function _authorizeHub(address relayManager, address relayHub) internal {\n authorizedHubs[relayManager][relayHub].removalTime = type(uint256).max;\n emit HubAuthorized(relayManager, relayHub);\n }\n\n /// @inheritdoc IStakeManager\n function unauthorizeHubByOwner(address relayManager, address relayHub) external override relayOwnerOnly(relayManager) {\n _unauthorizeHub(relayManager, relayHub);\n }\n\n /// @inheritdoc IStakeManager\n function unauthorizeHubByManager(address relayHub) external override managerOnly {\n _unauthorizeHub(msg.sender, relayHub);\n }\n\n function _unauthorizeHub(address relayManager, address relayHub) internal {\n RelayHubInfo storage hubInfo = authorizedHubs[relayManager][relayHub];\n require(hubInfo.removalTime == type(uint256).max, \"hub not authorized\");\n hubInfo.removalTime = block.timestamp + stakes[relayManager].unstakeDelay;\n emit HubUnauthorized(relayManager, relayHub, hubInfo.removalTime);\n }\n\n /// @inheritdoc IStakeManager\n function penalizeRelayManager(address relayManager, address beneficiary, uint256 amount) external override {\n uint256 removalTime = authorizedHubs[relayManager][msg.sender].removalTime;\n require(removalTime != 0, \"hub not authorized\");\n require(removalTime > block.timestamp, \"hub authorization expired\");\n\n // Half of the stake will be burned (sent to address 0)\n require(stakes[relayManager].stake >= amount, \"penalty exceeds stake\");\n stakes[relayManager].stake =stakes[relayManager].stake - amount;\n\n uint256 toBurn = amount / 2;\n uint256 reward = amount - toBurn;\n\n // Stake ERC-20 token is burned and transferred\n stakes[relayManager].token.safeTransfer(burnAddress, toBurn);\n stakes[relayManager].token.safeTransfer(beneficiary, reward);\n emit StakePenalized(relayManager, beneficiary, stakes[relayManager].token, reward);\n }\n\n /// @inheritdoc IStakeManager\n function isRelayEscheatable(address relayManager) public view override returns (bool) {\n IStakeManager.StakeInfo memory stakeInfo = stakes[relayManager];\n return stakeInfo.abandonedTime != 0 && stakeInfo.abandonedTime + abandonedRelayServerConfig.escheatmentDelay < block.timestamp;\n }\n\n /// @inheritdoc IStakeManager\n function markRelayAbandoned(address relayManager) external override onlyOwner {\n StakeInfo storage info = stakes[relayManager];\n require(info.stake > 0, \"relay manager not staked\");\n require(info.abandonedTime == 0, \"relay manager already abandoned\");\n require(info.keepaliveTime + abandonedRelayServerConfig.abandonmentDelay < block.timestamp, \"relay manager was alive recently\");\n info.abandonedTime = block.timestamp;\n emit RelayServerAbandoned(relayManager, info.abandonedTime);\n }\n\n /// @inheritdoc IStakeManager\n function escheatAbandonedRelayStake(address relayManager) external override onlyOwner {\n StakeInfo storage info = stakes[relayManager];\n require(isRelayEscheatable(relayManager), \"relay server not escheatable yet\");\n uint256 amount = info.stake;\n info.stake = 0;\n info.withdrawTime = 0;\n info.token.safeTransfer(abandonedRelayServerConfig.devAddress, amount);\n emit AbandonedRelayManagerStakeEscheated(relayManager, msg.sender, info.token, amount);\n }\n\n /// @inheritdoc IStakeManager\n function updateRelayKeepaliveTime(address relayManager) external override {\n StakeInfo storage info = stakes[relayManager];\n bool isHubAuthorized = authorizedHubs[relayManager][msg.sender].removalTime == type(uint256).max;\n bool isRelayOwner = info.owner == msg.sender;\n require(isHubAuthorized || isRelayOwner, \"must be called by owner or hub\");\n info.abandonedTime = 0;\n info.keepaliveTime = block.timestamp;\n emit RelayServerKeepalive(relayManager, info.keepaliveTime);\n }\n}\n" + }, + "@opengsn/contracts/src/test/TestPaymasterConfigurableMisbehavior.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./TestPaymasterEverythingAccepted.sol\";\n\ncontract TestPaymasterConfigurableMisbehavior is TestPaymasterEverythingAccepted {\n\n bool public withdrawDuringPostRelayedCall;\n bool public withdrawDuringPreRelayedCall;\n bool public returnInvalidErrorCode;\n bool public revertPostRelayCall;\n bool public outOfGasPre;\n bool public revertPreRelayCall;\n bool public revertPreRelayCallOnEvenBlocks;\n bool public greedyAcceptanceBudget;\n bool public expensiveGasLimits;\n\n function setWithdrawDuringPostRelayedCall(bool val) public {\n withdrawDuringPostRelayedCall = val;\n }\n function setWithdrawDuringPreRelayedCall(bool val) public {\n withdrawDuringPreRelayedCall = val;\n }\n function setReturnInvalidErrorCode(bool val) public {\n returnInvalidErrorCode = val;\n }\n function setRevertPostRelayCall(bool val) public {\n revertPostRelayCall = val;\n }\n function setRevertPreRelayCall(bool val) public {\n revertPreRelayCall = val;\n }\n function setRevertPreRelayCallOnEvenBlocks(bool val) public {\n revertPreRelayCallOnEvenBlocks = val;\n }\n function setOutOfGasPre(bool val) public {\n outOfGasPre = val;\n }\n\n function setGreedyAcceptanceBudget(bool val) public {\n greedyAcceptanceBudget = val;\n }\n function setExpensiveGasLimits(bool val) public {\n expensiveGasLimits = val;\n }\n\n // solhint-disable-next-line no-empty-blocks\n function _verifyApprovalData(bytes calldata approvalData) internal virtual override view {}\n\n // solhint-disable-next-line no-empty-blocks\n function _verifyPaymasterData(GsnTypes.RelayRequest calldata relayRequest) internal virtual override view {}\n\n // solhint-disable reason-string\n // contains comments that are checked in tests\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n returns (bytes memory, bool) {\n (relayRequest, signature, approvalData, maxPossibleGas);\n if (outOfGasPre) {\n uint256 i = 0;\n while (true) {\n i++;\n }\n }\n\n require(!returnInvalidErrorCode, \"invalid code\");\n\n if (withdrawDuringPreRelayedCall) {\n withdrawAllBalance();\n }\n if (revertPreRelayCall) {\n revert(\"You asked me to revert, remember?\");\n }\n if (revertPreRelayCallOnEvenBlocks && block.number % 2 == 0) {\n revert(\"You asked me to revert on even blocks, remember?\");\n }\n return (\"\", trustRecipientRevert);\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n {\n (context, success, gasUseWithoutPost, relayData);\n if (withdrawDuringPostRelayedCall) {\n withdrawAllBalance();\n }\n if (revertPostRelayCall) {\n revert(\"You asked me to revert, remember?\");\n }\n }\n\n /// leaving withdrawal public and unprotected\n function withdrawAllBalance() public returns (uint256) {\n require(address(relayHub) != address(0), \"relay hub address not set\");\n uint256 balance = relayHub.balanceOf(address(this));\n relayHub.withdraw(payable(address(this)), balance);\n return balance;\n }\n\n IPaymaster.GasAndDataLimits private limits = super.getGasAndDataLimits();\n\n function getGasAndDataLimits()\n public override view\n returns (IPaymaster.GasAndDataLimits memory) {\n\n if (expensiveGasLimits) {\n uint256 sum;\n //memory access is 700gas, so we waste ~50000\n for ( int256 i=0; i<100000; i+=700 ) {\n sum = sum + limits.acceptanceBudget;\n }\n }\n if (greedyAcceptanceBudget) {\n return IPaymaster.GasAndDataLimits(limits.acceptanceBudget * 9, limits.preRelayedCallGasLimit, limits.postRelayedCallGasLimit,\n limits.calldataSizeLimit);\n }\n return limits;\n }\n\n bool private trustRecipientRevert;\n\n function setGasLimits(uint256 acceptanceBudget, uint256 preRelayedCallGasLimit, uint256 postRelayedCallGasLimit) public {\n limits = IPaymaster.GasAndDataLimits(\n acceptanceBudget,\n preRelayedCallGasLimit,\n postRelayedCallGasLimit,\n limits.calldataSizeLimit\n );\n }\n\n function setTrustRecipientRevert(bool on) public {\n trustRecipientRevert = on;\n }\n\n // solhint-disable-next-line no-empty-blocks\n receive() external override payable {}\n}\n" + }, + "@opengsn/contracts/src/test/TestPaymasterEverythingAccepted.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../forwarder/IForwarder.sol\";\nimport \"../BasePaymaster.sol\";\n\ncontract TestPaymasterEverythingAccepted is BasePaymaster {\n\n function versionPaymaster() external view override virtual returns (string memory){\n return \"3.0.0-beta.3+opengsn.test-pea.ipaymaster\";\n }\n\n event SampleRecipientPreCall();\n event SampleRecipientPostCall(bool success, uint256 actualCharge);\n\n // solhint-disable-next-line no-empty-blocks\n function _verifyValue(GsnTypes.RelayRequest calldata) internal override view{}\n\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n virtual\n returns (bytes memory, bool) {\n (relayRequest, signature);\n (approvalData, maxPossibleGas);\n emit SampleRecipientPreCall();\n return (\"no revert here\",false);\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n virtual\n {\n (context, gasUseWithoutPost, relayData);\n emit SampleRecipientPostCall(success, gasUseWithoutPost);\n }\n\n function deposit() public payable {\n require(address(relayHub) != address(0), \"relay hub address not set\");\n relayHub.depositFor{value:msg.value}(address(this));\n }\n\n function withdrawAll(address payable destination) public {\n uint256 amount = relayHub.balanceOf(address(this));\n withdrawRelayHubDepositTo(amount, destination);\n }\n}\n" + }, + "@opengsn/contracts/src/test/TestRecipient.sol": { + "content": "/* solhint-disable avoid-tx-origin */\n// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\n\nimport \"../utils/GsnUtils.sol\";\nimport \"../ERC2771Recipient.sol\";\nimport \"./TestPaymasterConfigurableMisbehavior.sol\";\n\ncontract TestRecipient is ERC2771Recipient {\n\n constructor(address forwarder) {\n _setTrustedForwarder(forwarder);\n }\n\n // testing inner call gas estimation\n uint256 private nothing1;\n uint256 private nothing2;\n uint256 private nothing3;\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n nothing1 = type(uint256).max;\n nothing2 = type(uint256).max;\n nothing3 = type(uint256).max;\n }\n\n event Reverting(string message);\n\n function testRevert() public {\n require(address(this) == address(0), \"always fail\");\n emit Reverting(\"if you see this revert failed...\");\n }\n\n address payable public paymaster;\n\n function setWithdrawDuringRelayedCall(address payable _paymaster) public {\n paymaster = _paymaster;\n }\n\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n\n event SampleRecipientEmitted(string message, address realSender, address msgSender, address origin, uint256 msgValue, uint256 gasLeft, uint256 balance);\n\n function recipientRevert() public {\n revert(\"this method reverts consistently\");\n }\n\n function emitMessage(string memory message) public payable returns (string memory) {\n uint256 gasLeft = gasleft();\n if (paymaster != address(0)) {\n withdrawAllBalance();\n }\n\n emit SampleRecipientEmitted(message, _msgSender(), msg.sender, tx.origin, msg.value, gasLeft, address(this).balance);\n return \"emitMessage return value\";\n }\n\n function withdrawAllBalance() public {\n TestPaymasterConfigurableMisbehavior(paymaster).withdrawAllBalance();\n }\n\n // solhint-disable-next-line no-empty-blocks\n function dontEmitMessage(string calldata message) public {}\n\n function emitMessageNoParams() public {\n emit SampleRecipientEmitted(\"Method with no parameters\", _msgSender(), msg.sender, tx.origin, 0, gasleft(), address(this).balance);\n }\n\n //return (or revert) with a string in the given length\n function checkReturnValues(uint256 len, bool doRevert) public view returns (string memory) {\n (this);\n string memory mesg = \"this is a long message that we are going to return a small part from. we don't use a loop since we want a fixed gas usage of the method itself.\";\n require( bytes(mesg).length>=len, \"invalid len: too large\");\n\n /* solhint-disable no-inline-assembly */\n //cut the msg at that length\n assembly { mstore(mesg, len) }\n require(!doRevert, mesg);\n return mesg;\n }\n\n //function with no return value (also test revert with no msg.\n function checkNoReturnValues(bool doRevert) public view {\n (this);\n /* solhint-disable reason-string*/\n require(!doRevert);\n }\n\n function withdrawFromSingletonWhitelistPaymaster(address payable singletonPaymaster) public {\n TestRecipient(singletonPaymaster).withdrawBalance(1);\n }\n\n // only here for one method sig\n // solhint-disable-next-line no-empty-blocks\n function withdrawBalance(uint256 amount) public {}\n\n // only here for one method sig\n // solhint-disable-next-line no-empty-blocks\n function captureTheFlag() external {}\n}\n" + }, + "@opengsn/contracts/src/test/TestToken.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n\n constructor() ERC20(\"Test Token\", \"TOK\") {\n mint(100 ether);\n }\n\n function mint(uint256 amount) public {\n _mint(msg.sender, amount);\n }\n}\n" + }, + "@opengsn/contracts/src/utils/GsnEip712Library.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../utils/GsnTypes.sol\";\nimport \"../interfaces/IERC2771Recipient.sol\";\nimport \"../forwarder/IForwarder.sol\";\n\nimport \"./GsnUtils.sol\";\n\n/**\n * @title The ERC-712 Library for GSN\n * @notice Bridge Library to convert a GSN RelayRequest into a valid `ForwardRequest` for a `Forwarder`.\n */\nlibrary GsnEip712Library {\n // maximum length of return value/revert reason for 'execute' method. Will truncate result if exceeded.\n uint256 private constant MAX_RETURN_SIZE = 1024;\n\n //copied from Forwarder (can't reference string constants even from another library)\n string public constant GENERIC_PARAMS = \"address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data,uint256 validUntilTime\";\n\n bytes public constant RELAYDATA_TYPE = \"RelayData(uint256 maxFeePerGas,uint256 maxPriorityFeePerGas,uint256 transactionCalldataGasUsed,address relayWorker,address paymaster,address forwarder,bytes paymasterData,uint256 clientId)\";\n\n string public constant RELAY_REQUEST_NAME = \"RelayRequest\";\n string public constant RELAY_REQUEST_SUFFIX = string(abi.encodePacked(\"RelayData relayData)\", RELAYDATA_TYPE));\n\n bytes public constant RELAY_REQUEST_TYPE = abi.encodePacked(\n RELAY_REQUEST_NAME,\"(\",GENERIC_PARAMS,\",\", RELAY_REQUEST_SUFFIX);\n\n bytes32 public constant RELAYDATA_TYPEHASH = keccak256(RELAYDATA_TYPE);\n bytes32 public constant RELAY_REQUEST_TYPEHASH = keccak256(RELAY_REQUEST_TYPE);\n\n\n struct EIP712Domain {\n string name;\n string version;\n uint256 chainId;\n address verifyingContract;\n }\n\n bytes32 public constant EIP712DOMAIN_TYPEHASH = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n\n function splitRequest(\n GsnTypes.RelayRequest calldata req\n )\n internal\n pure\n returns (\n bytes memory suffixData\n ) {\n suffixData = abi.encode(\n hashRelayData(req.relayData));\n }\n\n //verify that the recipient trusts the given forwarder\n // MUST be called by paymaster\n function verifyForwarderTrusted(GsnTypes.RelayRequest calldata relayRequest) internal view {\n (bool success, bytes memory ret) = relayRequest.request.to.staticcall(\n abi.encodeWithSelector(\n IERC2771Recipient.isTrustedForwarder.selector, relayRequest.relayData.forwarder\n )\n );\n require(success, \"isTrustedForwarder: reverted\");\n require(ret.length == 32, \"isTrustedForwarder: bad response\");\n require(abi.decode(ret, (bool)), \"invalid forwarder for recipient\");\n }\n\n function verifySignature(\n string memory domainSeparatorName,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature\n ) internal view {\n (bytes memory suffixData) = splitRequest(relayRequest);\n bytes32 _domainSeparator = domainSeparator(domainSeparatorName, relayRequest.relayData.forwarder);\n IForwarder forwarder = IForwarder(payable(relayRequest.relayData.forwarder));\n forwarder.verify(relayRequest.request, _domainSeparator, RELAY_REQUEST_TYPEHASH, suffixData, signature);\n }\n\n function verify(\n string memory domainSeparatorName,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature\n ) internal view {\n verifyForwarderTrusted(relayRequest);\n verifySignature(domainSeparatorName, relayRequest, signature);\n }\n\n function execute(\n string memory domainSeparatorName,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature\n ) internal returns (\n bool forwarderSuccess,\n bool callSuccess,\n bytes memory ret\n ) {\n (bytes memory suffixData) = splitRequest(relayRequest);\n bytes32 _domainSeparator = domainSeparator(domainSeparatorName, relayRequest.relayData.forwarder);\n /* solhint-disable-next-line avoid-low-level-calls */\n (forwarderSuccess, ret) = relayRequest.relayData.forwarder.call(\n abi.encodeWithSelector(IForwarder.execute.selector,\n relayRequest.request, _domainSeparator, RELAY_REQUEST_TYPEHASH, suffixData, signature\n ));\n if ( forwarderSuccess ) {\n\n //decode return value of execute:\n (callSuccess, ret) = abi.decode(ret, (bool, bytes));\n }\n truncateInPlace(ret);\n }\n\n //truncate the given parameter (in-place) if its length is above the given maximum length\n // do nothing otherwise.\n //NOTE: solidity warns unless the method is marked \"pure\", but it DOES modify its parameter.\n function truncateInPlace(bytes memory data) internal pure {\n MinLibBytes.truncateInPlace(data, MAX_RETURN_SIZE);\n }\n\n function domainSeparator(string memory name, address forwarder) internal view returns (bytes32) {\n return hashDomain(EIP712Domain({\n name : name,\n version : \"3\",\n chainId : getChainID(),\n verifyingContract : forwarder\n }));\n }\n\n function getChainID() internal view returns (uint256 id) {\n /* solhint-disable no-inline-assembly */\n assembly {\n id := chainid()\n }\n }\n\n function hashDomain(EIP712Domain memory req) internal pure returns (bytes32) {\n return keccak256(abi.encode(\n EIP712DOMAIN_TYPEHASH,\n keccak256(bytes(req.name)),\n keccak256(bytes(req.version)),\n req.chainId,\n req.verifyingContract));\n }\n\n function hashRelayData(GsnTypes.RelayData calldata req) internal pure returns (bytes32) {\n return keccak256(abi.encode(\n RELAYDATA_TYPEHASH,\n req.maxFeePerGas,\n req.maxPriorityFeePerGas,\n req.transactionCalldataGasUsed,\n req.relayWorker,\n req.paymaster,\n req.forwarder,\n keccak256(req.paymasterData),\n req.clientId\n ));\n }\n}\n" + }, + "@opengsn/contracts/src/utils/GsnTypes.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\n\nimport \"../forwarder/IForwarder.sol\";\n\ninterface GsnTypes {\n /// @notice maxFeePerGas, maxPriorityFeePerGas, pctRelayFee and baseRelayFee must be validated inside of the paymaster's preRelayedCall in order not to overpay\n struct RelayData {\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n uint256 transactionCalldataGasUsed;\n address relayWorker;\n address paymaster;\n address forwarder;\n bytes paymasterData;\n uint256 clientId;\n }\n\n //note: must start with the ForwardRequest to be an extension of the generic forwarder\n struct RelayRequest {\n IForwarder.ForwardRequest request;\n RelayData relayData;\n }\n}\n" + }, + "@opengsn/contracts/src/utils/GsnUtils.sol": { + "content": "/* solhint-disable no-inline-assembly */\n// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\n\nimport \"../utils/MinLibBytes.sol\";\nimport \"./GsnTypes.sol\";\n\n/**\n * @title The GSN Solidity Utils Library\n * @notice Some library functions used throughout the GSN Solidity codebase.\n */\nlibrary GsnUtils {\n\n bytes32 constant private RELAY_REQUEST_ID_MASK = 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n /**\n * @notice Calculate an identifier for the meta-transaction in a format similar to a transaction hash.\n * Note that uniqueness relies on signature and may not be enforced if meta-transactions are verified\n * with a different algorithm, e.g. when batching.\n * @param relayRequest The `RelayRequest` for which an ID is being calculated.\n * @param signature The signature for the `RelayRequest`. It is not validated here and may even remain empty.\n */\n function getRelayRequestID(GsnTypes.RelayRequest calldata relayRequest, bytes calldata signature)\n internal\n pure\n returns (bytes32) {\n return keccak256(abi.encode(relayRequest.request.from, relayRequest.request.nonce, signature)) & RELAY_REQUEST_ID_MASK;\n }\n\n /**\n * @notice Extract the method identifier signature from the encoded function call.\n */\n function getMethodSig(bytes memory msgData) internal pure returns (bytes4) {\n return MinLibBytes.readBytes4(msgData, 0);\n }\n\n /**\n * @notice Extract a parameter from encoded-function block.\n * see: https://solidity.readthedocs.io/en/develop/abi-spec.html#formal-specification-of-the-encoding\n * The return value should be casted to the right type (`uintXXX`/`bytesXXX`/`address`/`bool`/`enum`).\n * @param msgData Byte array containing a uint256 value.\n * @param index Index in byte array of uint256 value.\n * @return result uint256 value from byte array.\n */\n function getParam(bytes memory msgData, uint256 index) internal pure returns (uint256 result) {\n return MinLibBytes.readUint256(msgData, 4 + index * 32);\n }\n\n /// @notice Re-throw revert with the same revert data.\n function revertWithData(bytes memory data) internal pure {\n assembly {\n revert(add(data,32), mload(data))\n }\n }\n\n}\n" + }, + "@opengsn/contracts/src/utils/MinLibBytes.sol": { + "content": "// SPDX-License-Identifier: MIT\n// minimal bytes manipulation required by GSN\n// a minimal subset from 0x/LibBytes\n/* solhint-disable no-inline-assembly */\npragma solidity ^0.8.0;\n\nlibrary MinLibBytes {\n\n //truncate the given parameter (in-place) if its length is above the given maximum length\n // do nothing otherwise.\n //NOTE: solidity warns unless the method is marked \"pure\", but it DOES modify its parameter.\n function truncateInPlace(bytes memory data, uint256 maxlen) internal pure {\n if (data.length > maxlen) {\n assembly { mstore(data, maxlen) }\n }\n }\n\n /// @dev Reads an address from a position in a byte array.\n /// @param b Byte array containing an address.\n /// @param index Index in byte array of address.\n /// @return result address from byte array.\n function readAddress(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (address result)\n {\n require (b.length >= index + 20, \"readAddress: data too short\");\n\n // Add offset to index:\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\n index += 20;\n\n // Read address from array memory\n assembly {\n // 1. Add index to address of bytes array\n // 2. Load 32-byte word from memory\n // 3. Apply 20-byte mask to obtain address\n result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)\n }\n return result;\n }\n\n function readBytes32(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes32 result)\n {\n require(b.length >= index + 32, \"readBytes32: data too short\" );\n\n // Read the bytes32 from array memory\n assembly {\n result := mload(add(b, add(index,32)))\n }\n return result;\n }\n\n /// @dev Reads a uint256 value from a position in a byte array.\n /// @param b Byte array containing a uint256 value.\n /// @param index Index in byte array of uint256 value.\n /// @return result uint256 value from byte array.\n function readUint256(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (uint256 result)\n {\n result = uint256(readBytes32(b, index));\n return result;\n }\n\n function readBytes4(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes4 result)\n {\n require(b.length >= index + 4, \"readBytes4: data too short\");\n\n // Read the bytes4 from array memory\n assembly {\n result := mload(add(b, add(index,32)))\n // Solidity does not require us to clean the trailing bytes.\n // We do it anyway\n result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)\n }\n return result;\n }\n}\n" + }, + "@opengsn/contracts/src/utils/RelayHubValidator.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../utils/GsnTypes.sol\";\n\n/**\n * @title The RelayHub Validator Library\n * @notice Validates the `msg.data` received by the `RelayHub` does not contain unnecessary bytes.\n * Including these extra bytes would allow the Relay Server to inflate transaction costs and overcharge the client.\n */\nlibrary RelayHubValidator {\n\n /// @notice Validate that encoded `relayCall` is properly packed without any extra bytes\n function verifyTransactionPacking(\n string calldata domainSeparatorName,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData\n ) internal pure {\n // abicoder v2: https://docs.soliditylang.org/en/latest/abi-spec.html\n // each static param/member is 1 word\n // struct (with dynamic members) has offset to struct which is 1 word\n // dynamic member is 1 word offset to actual value, which is 1-word length and ceil(length/32) words for data\n // relayCall has 5 method params,\n // relayRequest: 2 members\n // relayData 8 members\n // ForwardRequest: 7 members\n // total 21 32-byte words if all dynamic params are zero-length.\n uint256 expectedMsgDataLen = 4 + 22 * 32 +\n dynamicParamSize(bytes(domainSeparatorName)) +\n dynamicParamSize(signature) +\n dynamicParamSize(approvalData) +\n dynamicParamSize(relayRequest.request.data) +\n dynamicParamSize(relayRequest.relayData.paymasterData);\n // zero-length signature is allowed in a batch relay transaction\n require(expectedMsgDataLen == msg.data.length, \"extra msg.data bytes\" );\n }\n\n // helper method for verifyTransactionPacking:\n // size (in bytes) of the given \"bytes\" parameter. size include the length (32-byte word),\n // and actual data size, rounded up to full 32-byte words\n function dynamicParamSize(bytes calldata buf) internal pure returns (uint256) {\n return 32 + ((buf.length + 31) & (type(uint256).max - 31));\n }\n}\n" + }, + "@opengsn/contracts/src/utils/RelayRegistrar.sol": { + "content": "// solhint-disable not-rely-on-time\n//SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.6;\n/* solhint-disable no-inline-assembly */\n\n// #if ENABLE_CONSOLE_LOG\nimport \"hardhat/console.sol\";\n// #endif\n\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./MinLibBytes.sol\";\nimport \"../interfaces/IRelayHub.sol\";\nimport \"../interfaces/IRelayRegistrar.sol\";\n\n/**\n * @title The RelayRegistrar Implementation\n * @notice Keeps a list of registered relayers.\n *\n * @notice Provides view functions to read the list of registered relayers and filters out invalid ones.\n *\n * @notice Protects the list from spamming entries: only staked relayers are added.\n */\ncontract RelayRegistrar is IRelayRegistrar, Ownable, ERC165 {\n using MinLibBytes for bytes;\n\n uint256 private constant MAX_RELAYS_RETURNED_COUNT = 1000;\n\n /// @notice Mapping from `RelayHub` address to a mapping from a Relay Manager address to its registration details.\n mapping(address => mapping(address => RelayInfo)) internal values;\n\n /// @notice Mapping from `RelayHub` address to an array of Relay Managers that are registered on that `RelayHub`.\n mapping(address => address[]) internal indexedValues;\n\n uint256 private immutable creationBlock;\n\n uint256 private relayRegistrationMaxAge;\n\n constructor(uint256 _relayRegistrationMaxAge) {\n setRelayRegistrationMaxAge(_relayRegistrationMaxAge);\n creationBlock = block.number;\n }\n\n /// @inheritdoc IRelayRegistrar\n function getCreationBlock() external override view returns (uint256){\n return creationBlock;\n }\n\n /// @inheritdoc IRelayRegistrar\n function getRelayRegistrationMaxAge() external override view returns (uint256){\n return relayRegistrationMaxAge;\n }\n\n /// @inheritdoc IRelayRegistrar\n function setRelayRegistrationMaxAge(uint256 _relayRegistrationMaxAge) public override onlyOwner {\n relayRegistrationMaxAge = _relayRegistrationMaxAge;\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n return interfaceId == type(IRelayRegistrar).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IRelayRegistrar\n function registerRelayServer(\n address relayHub,\n bytes32[3] calldata url\n ) external override {\n address relayManager = msg.sender;\n IRelayHub(relayHub).onRelayServerRegistered(relayManager);\n emit RelayServerRegistered(relayManager, relayHub, url);\n storeRelayServerRegistration(relayManager, relayHub, url);\n }\n\n function addItem(address relayHub, address relayManager) internal returns (RelayInfo storage) {\n RelayInfo storage storageInfo = values[relayHub][relayManager];\n if (storageInfo.lastSeenBlockNumber == 0) {\n indexedValues[relayHub].push(relayManager);\n }\n return storageInfo;\n }\n\n function storeRelayServerRegistration(\n address relayManager,\n address relayHub,\n bytes32[3] calldata url\n ) internal {\n RelayInfo storage storageInfo = addItem(relayHub, relayManager);\n if (storageInfo.firstSeenBlockNumber == 0) {\n storageInfo.firstSeenBlockNumber = uint32(block.number);\n storageInfo.firstSeenTimestamp = uint40(block.timestamp);\n }\n storageInfo.lastSeenBlockNumber = uint32(block.number);\n storageInfo.lastSeenTimestamp = uint40(block.timestamp);\n storageInfo.relayManager = relayManager;\n storageInfo.urlParts = url;\n }\n\n /// @inheritdoc IRelayRegistrar\n function getRelayInfo(address relayHub, address relayManager) public view override returns (RelayInfo memory) {\n RelayInfo memory info = values[relayHub][relayManager];\n require(info.lastSeenBlockNumber != 0, \"relayManager not found\");\n return info;\n }\n\n /// @inheritdoc IRelayRegistrar\n function readRelayInfos(\n address relayHub\n )\n public\n view\n override\n returns (\n RelayInfo[] memory info\n ) {\n uint256 blockTimestamp = block.timestamp;\n uint256 oldestBlockTimestamp = blockTimestamp >= relayRegistrationMaxAge ? blockTimestamp - relayRegistrationMaxAge : 0;\n return readRelayInfosInRange(relayHub, 0, oldestBlockTimestamp, MAX_RELAYS_RETURNED_COUNT);\n }\n\n /// @inheritdoc IRelayRegistrar\n function readRelayInfosInRange(\n address relayHub,\n uint256 oldestBlockNumber,\n uint256 oldestBlockTimestamp,\n uint256 maxCount\n )\n public\n view\n override\n returns (\n RelayInfo[] memory info\n ) {\n address[] storage items = indexedValues[relayHub];\n uint256 filled = 0;\n info = new RelayInfo[](items.length < maxCount ? items.length : maxCount);\n for (uint256 i = 0; i < items.length; i++) {\n address relayManager = items[i];\n RelayInfo memory relayInfo = getRelayInfo(relayHub, relayManager);\n if (\n relayInfo.lastSeenBlockNumber < oldestBlockNumber ||\n relayInfo.lastSeenTimestamp < oldestBlockTimestamp\n ) {\n continue;\n }\n // solhint-disable-next-line no-empty-blocks\n try IRelayHub(relayHub).verifyRelayManagerStaked(relayManager) {\n } catch (bytes memory /*lowLevelData*/) {\n continue;\n }\n info[filled++] = relayInfo;\n if (filled >= maxCount)\n break;\n }\n assembly { mstore(info, filled) }\n }\n}\n" + }, + "@opengsn/contracts/src/utils/RLPReader.sol": { + "content": "// SPDX-License-Identifier:APACHE-2.0\n/*\n* Taken from https://github.com/hamdiallam/Solidity-RLP\n*/\n/* solhint-disable */\npragma solidity ^0.8.0;\n\nlibrary RLPReader {\n\n uint8 constant STRING_SHORT_START = 0x80;\n uint8 constant STRING_LONG_START = 0xb8;\n uint8 constant LIST_SHORT_START = 0xc0;\n uint8 constant LIST_LONG_START = 0xf8;\n uint8 constant WORD_SIZE = 32;\n\n struct RLPItem {\n uint len;\n uint memPtr;\n }\n\n using RLPReader for bytes;\n using RLPReader for uint;\n using RLPReader for RLPReader.RLPItem;\n\n // helper function to decode rlp encoded legacy ethereum transaction\n /*\n * @param rawTransaction RLP encoded legacy ethereum transaction rlp([nonce, gasPrice, gasLimit, to, value, data]))\n * @return tuple (nonce,gasLimit,to,value,data)\n */\n\n function decodeLegacyTransaction(bytes calldata rawTransaction) internal pure returns (uint, uint, address, uint, bytes memory){\n RLPReader.RLPItem[] memory values = rawTransaction.toRlpItem().toList(); // must convert to an rlpItem first!\n return (values[0].toUint(), values[2].toUint(), values[3].toAddress(), values[4].toUint(), values[5].toBytes());\n }\n\n /*\n * @param rawTransaction format: 0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, access_list]))\n * @return tuple (nonce,gasLimit,to,value,data)\n */\n function decodeTransactionType1(bytes calldata rawTransaction) internal pure returns (uint, uint, address, uint, bytes memory){\n bytes memory payload = rawTransaction[1:rawTransaction.length];\n RLPReader.RLPItem[] memory values = payload.toRlpItem().toList(); // must convert to an rlpItem first!\n return (values[1].toUint(), values[3].toUint(), values[4].toAddress(), values[5].toUint(), values[6].toBytes());\n }\n\n /*\n * @param rawTransaction format: 0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list]))\n * @return tuple (nonce,gasLimit,to,value,data)\n */\n function decodeTransactionType2(bytes calldata rawTransaction) internal pure returns (uint, uint, address, uint, bytes memory){\n bytes memory payload = rawTransaction[1:rawTransaction.length];\n RLPReader.RLPItem[] memory values = payload.toRlpItem().toList(); // must convert to an rlpItem first!\n return (values[1].toUint(), values[4].toUint(), values[5].toAddress(), values[6].toUint(), values[7].toBytes());\n }\n\n /*\n * @param item RLP encoded bytes\n */\n function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {\n if (item.length == 0)\n return RLPItem(0, 0);\n uint memPtr;\n assembly {\n memPtr := add(item, 0x20)\n }\n return RLPItem(item.length, memPtr);\n }\n /*\n * @param item RLP encoded list in bytes\n */\n function toList(RLPItem memory item) internal pure returns (RLPItem[] memory result) {\n require(isList(item), \"isList failed\");\n uint items = numItems(item);\n result = new RLPItem[](items);\n uint memPtr = item.memPtr + _payloadOffset(item.memPtr);\n uint dataLen;\n for (uint i = 0; i < items; i++) {\n dataLen = _itemLength(memPtr);\n result[i] = RLPItem(dataLen, memPtr);\n memPtr = memPtr + dataLen;\n }\n }\n /*\n * Helpers\n */\n // @return indicator whether encoded payload is a list. negate this function call for isData.\n function isList(RLPItem memory item) internal pure returns (bool) {\n uint8 byte0;\n uint memPtr = item.memPtr;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n if (byte0 < LIST_SHORT_START)\n return false;\n return true;\n }\n // @return number of payload items inside an encoded list.\n function numItems(RLPItem memory item) internal pure returns (uint) {\n uint count = 0;\n uint currPtr = item.memPtr + _payloadOffset(item.memPtr);\n uint endPtr = item.memPtr + item.len;\n while (currPtr < endPtr) {\n currPtr = currPtr + _itemLength(currPtr);\n // skip over an item\n count++;\n }\n return count;\n }\n // @return entire rlp item byte length\n function _itemLength(uint memPtr) internal pure returns (uint len) {\n uint byte0;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n if (byte0 < STRING_SHORT_START)\n return 1;\n else if (byte0 < STRING_LONG_START)\n return byte0 - STRING_SHORT_START + 1;\n else if (byte0 < LIST_SHORT_START) {\n assembly {\n let byteLen := sub(byte0, 0xb7) // number of bytes the actual length is\n memPtr := add(memPtr, 1) // skip over the first byte\n /* 32 byte word size */\n let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len\n len := add(dataLen, add(byteLen, 1))\n }\n }\n else if (byte0 < LIST_LONG_START) {\n return byte0 - LIST_SHORT_START + 1;\n }\n else {\n assembly {\n let byteLen := sub(byte0, 0xf7)\n memPtr := add(memPtr, 1)\n let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length\n len := add(dataLen, add(byteLen, 1))\n }\n }\n }\n // @return number of bytes until the data\n function _payloadOffset(uint memPtr) internal pure returns (uint) {\n uint byte0;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n if (byte0 < STRING_SHORT_START)\n return 0;\n else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START))\n return 1;\n else if (byte0 < LIST_SHORT_START) // being explicit\n return byte0 - (STRING_LONG_START - 1) + 1;\n else\n return byte0 - (LIST_LONG_START - 1) + 1;\n }\n /** RLPItem conversions into data types **/\n // @returns raw rlp encoding in bytes\n function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {\n bytes memory result = new bytes(item.len);\n uint ptr;\n assembly {\n ptr := add(0x20, result)\n }\n copy(item.memPtr, ptr, item.len);\n return result;\n }\n\n function toBoolean(RLPItem memory item) internal pure returns (bool) {\n require(item.len == 1, \"Invalid RLPItem. Booleans are encoded in 1 byte\");\n uint result;\n uint memPtr = item.memPtr;\n assembly {\n result := byte(0, mload(memPtr))\n }\n return result == 0 ? false : true;\n }\n\n function toAddress(RLPItem memory item) internal pure returns (address) {\n // 1 byte for the length prefix according to RLP spec\n require(item.len <= 21, \"Invalid RLPItem. Addresses are encoded in 20 bytes or less\");\n return address(uint160(toUint(item)));\n }\n\n function toUint(RLPItem memory item) internal pure returns (uint) {\n uint offset = _payloadOffset(item.memPtr);\n uint len = item.len - offset;\n uint memPtr = item.memPtr + offset;\n uint result;\n assembly {\n result := div(mload(memPtr), exp(256, sub(32, len))) // shift to the correct location\n }\n return result;\n }\n\n function toBytes(RLPItem memory item) internal pure returns (bytes memory) {\n uint offset = _payloadOffset(item.memPtr);\n uint len = item.len - offset;\n // data length\n bytes memory result = new bytes(len);\n uint destPtr;\n assembly {\n destPtr := add(0x20, result)\n }\n copy(item.memPtr + offset, destPtr, len);\n return result;\n }\n /*\n * @param src Pointer to source\n * @param dest Pointer to destination\n * @param len Amount of memory to copy from the source\n */\n function copy(uint src, uint dest, uint len) internal pure {\n if (len == 0) return;\n\n // copy as many word sizes as possible\n for (; len >= WORD_SIZE; len -= WORD_SIZE) {\n assembly {\n mstore(dest, mload(src))\n }\n\n src += WORD_SIZE;\n dest += WORD_SIZE;\n }\n\n if (len > 0) {\n // left over bytes. Mask is used to remove unwanted bytes from the word\n uint mask = 256 ** (WORD_SIZE - len) - 1;\n assembly {\n let srcpart := and(mload(src), not(mask)) // zero out src\n let destpart := and(mload(dest), mask) // retrieve the bytes\n mstore(dest, or(destpart, srcpart))\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../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 * By default, the owner account will be the one that deploys the contract. This\n * can 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 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\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 require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\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 require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165.sol\";\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\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" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\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 ÷ 2 + 1, and for v in (302): v ∈ {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 if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n /**\n * @dev Returns true if `account` supports the {IERC165} interface.\n */\n function supportsERC165(address account) internal view returns (bool) {\n // Any contract that implements ERC165 must explicitly indicate support of\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n return\n supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) &&\n !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID);\n }\n\n /**\n * @dev Returns true if `account` supports the interface defined by\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n // query support of both ERC165 as per the spec and support of _interfaceId\n return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId);\n }\n\n /**\n * @dev Returns a boolean array where each value corresponds to the\n * interfaces passed in and whether they're supported or not. This allows\n * you to batch check interfaces for a contract where your expectation\n * is that some interfaces may not be supported.\n *\n * See {IERC165-supportsInterface}.\n *\n * _Available since v3.4._\n */\n function getSupportedInterfaces(\n address account,\n bytes4[] memory interfaceIds\n ) internal view returns (bool[] memory) {\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n // query support of ERC165 itself\n if (supportsERC165(account)) {\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]);\n }\n }\n\n return interfaceIdsSupported;\n }\n\n /**\n * @dev Returns true if `account` supports all the interfaces defined in\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n *\n * Batch-querying can lead to gas savings by skipping repeated checks for\n * {IERC165} support.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n // query support of ERC165 itself\n if (!supportsERC165(account)) {\n return false;\n }\n\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) {\n return false;\n }\n }\n\n // all interfaces supported\n return true;\n }\n\n /**\n * @notice Query if a contract implements an interface, does not check ERC165 support\n * @param account The address of the contract to query for support of an interface\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @return true if the contract at account indicates support of the interface with\n * identifier interfaceId, false otherwise\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\n * the behavior of this method is undefined. This precondition can be checked\n * with {supportsERC165}.\n *\n * Some precompiled contracts will falsely indicate support for a given interface, so caution\n * should be exercised when using this function.\n *\n * Interface identification is specified in ERC-165.\n */\n function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {\n // prepare call\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n\n // perform static call\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly {\n success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0x00)\n }\n\n return success && returnSize >= 0x20 && returnValue > 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(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; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // 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 require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\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 // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `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 + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\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 + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Callback for IUniswapV3PoolActions#swap\n/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface\ninterface IUniswapV3SwapCallback {\n /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.\n /// @dev In the implementation you must pay the pool tokens owed for the swap.\n /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.\n /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.\n /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.\n /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by\n /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.\n /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call\n function uniswapV3SwapCallback(\n int256 amount0Delta,\n int256 amount1Delta,\n bytes calldata data\n ) external;\n}\n" + }, + "@uniswap/v3-periphery/contracts/interfaces/IPeripheryPayments.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.7.5;\n\n/// @title Periphery Payments\n/// @notice Functions to ease deposits and withdrawals of ETH\ninterface IPeripheryPayments {\n /// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH.\n /// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users.\n /// @param amountMinimum The minimum amount of WETH9 to unwrap\n /// @param recipient The address receiving ETH\n function unwrapWETH9(uint256 amountMinimum, address recipient) external payable;\n\n /// @notice Refunds any ETH balance held by this contract to the `msg.sender`\n /// @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps\n /// that use ether for the input amount\n function refundETH() external payable;\n\n /// @notice Transfers the full amount of a token held by this contract to recipient\n /// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users\n /// @param token The contract address of the token which will be transferred to `recipient`\n /// @param amountMinimum The minimum amount of token required for a transfer\n /// @param recipient The destination address of the token\n function sweepToken(\n address token,\n uint256 amountMinimum,\n address recipient\n ) external payable;\n}\n" + }, + "@uniswap/v3-periphery/contracts/interfaces/IQuoter.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.7.5;\npragma abicoder v2;\n\n/// @title Quoter Interface\n/// @notice Supports quoting the calculated amounts from exact input or exact output swaps\n/// @dev These functions are not marked view because they rely on calling non-view functions and reverting\n/// to compute the result. They are also not gas efficient and should not be called on-chain.\ninterface IQuoter {\n /// @notice Returns the amount out received for a given exact input swap without executing the swap\n /// @param path The path of the swap, i.e. each token pair and the pool fee\n /// @param amountIn The amount of the first token to swap\n /// @return amountOut The amount of the last token that would be received\n function quoteExactInput(bytes memory path, uint256 amountIn) external returns (uint256 amountOut);\n\n /// @notice Returns the amount out received for a given exact input but for a swap of a single pool\n /// @param tokenIn The token being swapped in\n /// @param tokenOut The token being swapped out\n /// @param fee The fee of the token pool to consider for the pair\n /// @param amountIn The desired input amount\n /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap\n /// @return amountOut The amount of `tokenOut` that would be received\n function quoteExactInputSingle(\n address tokenIn,\n address tokenOut,\n uint24 fee,\n uint256 amountIn,\n uint160 sqrtPriceLimitX96\n ) external returns (uint256 amountOut);\n\n /// @notice Returns the amount in required for a given exact output swap without executing the swap\n /// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order\n /// @param amountOut The amount of the last token to receive\n /// @return amountIn The amount of first token required to be paid\n function quoteExactOutput(bytes memory path, uint256 amountOut) external returns (uint256 amountIn);\n\n /// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool\n /// @param tokenIn The token being swapped in\n /// @param tokenOut The token being swapped out\n /// @param fee The fee of the token pool to consider for the pair\n /// @param amountOut The desired output amount\n /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap\n /// @return amountIn The amount required as the input for the swap in order to receive `amountOut`\n function quoteExactOutputSingle(\n address tokenIn,\n address tokenOut,\n uint24 fee,\n uint256 amountOut,\n uint160 sqrtPriceLimitX96\n ) external returns (uint256 amountIn);\n}\n" + }, + "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.7.5;\npragma abicoder v2;\n\nimport '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol';\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface ISwapRouter is IUniswapV3SwapCallback {\n struct ExactInputSingleParams {\n address tokenIn;\n address tokenOut;\n uint24 fee;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n uint160 sqrtPriceLimitX96;\n }\n\n /// @notice Swaps `amountIn` of one token for as much as possible of another token\n /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);\n\n struct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n }\n\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n\n struct ExactOutputSingleParams {\n address tokenIn;\n address tokenOut;\n uint24 fee;\n address recipient;\n uint256 deadline;\n uint256 amountOut;\n uint256 amountInMaximum;\n uint160 sqrtPriceLimitX96;\n }\n\n /// @notice Swaps as little as possible of one token for `amountOut` of another token\n /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata\n /// @return amountIn The amount of the input token\n function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);\n\n struct ExactOutputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountOut;\n uint256 amountInMaximum;\n }\n\n /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata\n /// @return amountIn The amount of the input token\n function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);\n}\n" + }, + "contracts-link/arbitrum/ArbRelayHub.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../RelayHub.sol\";\nimport \"./ArbSys.sol\";\n\n/**\n * @title The RelayHub Implementation for Arbitrum\n * @notice This contract implements the `IRelayHub` interface for the Arbitrum-compatible Rollups.\n *\n * @notice This implementation relies on the `ArbSys` built-ins that do not exist outside of Arbitrum.\n */\ncontract ArbRelayHub is RelayHub {\n\n /// @inheritdoc IRelayHub\n function versionHub() override public pure returns (string memory){\n return \"3.0.0-beta.3+opengsn.arbhub.irelayhub\";\n }\n\n ArbSys public immutable arbsys;\n uint256 internal immutable arbCreationBlock;\n\n /// @notice we accept the `ArbSys` address in the constructor to allow mocking it in tests.\n constructor(\n ArbSys _arbsys,\n IStakeManager _stakeManager,\n address _penalizer,\n address _batchGateway,\n address _relayRegistrar,\n RelayHubConfig memory _config\n ) RelayHub(_stakeManager, _penalizer, _batchGateway, _relayRegistrar, _config){\n arbsys = _arbsys;\n arbCreationBlock = _arbsys.arbBlockNumber();\n }\n\n /// @inheritdoc IRelayHub\n /// @notice Uses `ArbSys` L2 block number specific to the Arbitrum Rollup.\n function getCreationBlock() external override virtual view returns (uint256){\n return arbCreationBlock;\n }\n\n /// @return The block number in which the contract has been deployed.\n /// @notice Uses original L1 block number.\n function getL1CreationBlock() external view returns (uint256){\n return creationBlock;\n }\n\n /// @notice Includes the 'storage gas' specific to the Arbitrum Rollup.\n /// @inheritdoc IRelayHub\n function aggregateGasleft() public override virtual view returns (uint256){\n return arbsys.getStorageGasAvailable() + gasleft();\n }\n}" + }, + "contracts-link/arbitrum/ArbSys.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\n/**\n* @title Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064. Exposes a variety of system-level functionality.\n */\ninterface ArbSys {\n\n /**\n * @notice Get Arbitrum block number (distinct from L1 block number; Arbitrum genesis block has block number 0)\n * @return block number as int\n */\n function arbBlockNumber() external view returns (uint256);\n\n /**\n * @notice get the caller's amount of available storage gas\n * @return amount of storage gas available to the caller\n */\n function getStorageGasAvailable() external view returns (uint256);\n}" + }, + "contracts-link/BasePaymaster.sol": { + "content": "pragma solidity >=0.7.6;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\n\nimport \"./utils/GsnTypes.sol\";\nimport \"./interfaces/IPaymaster.sol\";\nimport \"./interfaces/IRelayHub.sol\";\nimport \"./utils/GsnEip712Library.sol\";\nimport \"./forwarder/IForwarder.sol\";\n\n/**\n * @notice An abstract base class to be inherited by a concrete Paymaster.\n * A subclass must implement:\n * - preRelayedCall\n * - postRelayedCall\n */\nabstract contract BasePaymaster is IPaymaster, Ownable, ERC165 {\n using ERC165Checker for address;\n\n IRelayHub internal relayHub;\n address private _trustedForwarder;\n\n /// @inheritdoc IPaymaster\n function getRelayHub() public override view returns (address) {\n return address(relayHub);\n }\n\n //overhead of forwarder verify+signature, plus hub overhead.\n uint256 constant public FORWARDER_HUB_OVERHEAD = 50000;\n\n //These parameters are documented in IPaymaster.GasAndDataLimits\n uint256 constant public PRE_RELAYED_CALL_GAS_LIMIT = 100000;\n uint256 constant public POST_RELAYED_CALL_GAS_LIMIT = 110000;\n uint256 constant public PAYMASTER_ACCEPTANCE_BUDGET = PRE_RELAYED_CALL_GAS_LIMIT + FORWARDER_HUB_OVERHEAD;\n uint256 constant public CALLDATA_SIZE_LIMIT = 10500;\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n return interfaceId == type(IPaymaster).interfaceId ||\n interfaceId == type(Ownable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IPaymaster\n function getGasAndDataLimits()\n public\n override\n virtual\n view\n returns (\n IPaymaster.GasAndDataLimits memory limits\n ) {\n return IPaymaster.GasAndDataLimits(\n PAYMASTER_ACCEPTANCE_BUDGET,\n PRE_RELAYED_CALL_GAS_LIMIT,\n POST_RELAYED_CALL_GAS_LIMIT,\n CALLDATA_SIZE_LIMIT\n );\n }\n\n /**\n * @notice this method must be called from preRelayedCall to validate that the forwarder\n * is approved by the paymaster as well as by the recipient contract.\n */\n function _verifyForwarder(GsnTypes.RelayRequest calldata relayRequest)\n internal\n virtual\n view\n {\n require(getTrustedForwarder() == relayRequest.relayData.forwarder, \"Forwarder is not trusted\");\n GsnEip712Library.verifyForwarderTrusted(relayRequest);\n }\n\n function _verifyRelayHubOnly() internal virtual view {\n require(msg.sender == getRelayHub(), \"can only be called by RelayHub\");\n }\n\n function _verifyValue(GsnTypes.RelayRequest calldata relayRequest) internal virtual view{\n require(relayRequest.request.value == 0, \"value transfer not supported\");\n }\n\n function _verifyPaymasterData(GsnTypes.RelayRequest calldata relayRequest) internal virtual view {\n require(relayRequest.relayData.paymasterData.length == 0, \"should have no paymasterData\");\n }\n\n function _verifyApprovalData(bytes calldata approvalData) internal virtual view{\n require(approvalData.length == 0, \"should have no approvalData\");\n }\n\n /**\n * @notice The owner of the Paymaster can change the instance of the RelayHub this Paymaster works with.\n * :warning: **Warning** :warning: The deposit on the previous RelayHub must be withdrawn first.\n */\n function setRelayHub(IRelayHub hub) public onlyOwner {\n require(address(hub).supportsInterface(type(IRelayHub).interfaceId), \"target is not a valid IRelayHub\");\n relayHub = hub;\n }\n\n /**\n * @notice The owner of the Paymaster can change the instance of the Forwarder this Paymaster works with.\n * @notice the Recipients must trust this Forwarder as well in order for the configuration to remain functional.\n */\n function setTrustedForwarder(address forwarder) public virtual onlyOwner {\n require(forwarder.supportsInterface(type(IForwarder).interfaceId), \"target is not a valid IForwarder\");\n _trustedForwarder = forwarder;\n }\n\n function getTrustedForwarder() public virtual view override returns (address){\n return _trustedForwarder;\n }\n\n /**\n * @notice Any native Ether transferred into the paymaster is transferred as a deposit to the RelayHub.\n * This way, we don't need to understand the RelayHub API in order to replenish the paymaster.\n */\n receive() external virtual payable {\n require(address(relayHub) != address(0), \"relay hub address not set\");\n relayHub.depositFor{value:msg.value}(address(this));\n }\n\n /**\n * @notice Withdraw deposit from the RelayHub.\n * @param amount The amount to be subtracted from the sender.\n * @param target The target to which the amount will be transferred.\n */\n function withdrawRelayHubDepositTo(uint256 amount, address payable target) public onlyOwner {\n relayHub.withdraw(target, amount);\n }\n\n /// @inheritdoc IPaymaster\n function preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n external\n override\n returns (bytes memory, bool) {\n _verifyRelayHubOnly();\n _verifyForwarder(relayRequest);\n _verifyValue(relayRequest);\n _verifyPaymasterData(relayRequest);\n _verifyApprovalData(approvalData);\n return _preRelayedCall(relayRequest, signature, approvalData, maxPossibleGas);\n }\n\n /**\n * @notice internal logic the paymasters need to provide to select which transactions they are willing to pay for\n * @notice see the documentation for `IPaymaster::preRelayedCall` for details\n */\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata,\n bytes calldata,\n bytes calldata,\n uint256\n )\n internal\n virtual\n returns (bytes memory, bool);\n\n /// @inheritdoc IPaymaster\n function postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n external\n override\n {\n _verifyRelayHubOnly();\n _postRelayedCall(context, success, gasUseWithoutPost, relayData);\n }\n\n /**\n * @notice internal logic the paymasters need to provide if they need to take some action after the transaction\n * @notice see the documentation for `IPaymaster::postRelayedCall` for details\n */\n function _postRelayedCall(\n bytes calldata,\n bool,\n uint256,\n GsnTypes.RelayData calldata\n )\n internal\n virtual;\n}" + }, + "contracts-link/ERC2771Recipient.sol": { + "content": "pragma solidity >=0.6.9;\n\n// SPDX-License-Identifier: MIT\n// solhint-disable no-inline-assembly\n\nimport \"./interfaces/IERC2771Recipient.sol\";\n\n/**\n * @title The ERC-2771 Recipient Base Abstract Class - Implementation\n *\n * @notice Note that this contract was called `BaseRelayRecipient` in the previous revision of the GSN.\n *\n * @notice A base contract to be inherited by any contract that want to receive relayed transactions.\n *\n * @notice A subclass must use `_msgSender()` instead of `msg.sender`.\n */\nabstract contract ERC2771Recipient is IERC2771Recipient {\n\n /*\n * Forwarder singleton we accept calls from\n */\n address private _trustedForwarder;\n\n /**\n * :warning: **Warning** :warning: The Forwarder can have a full control over your Recipient. Only trust verified Forwarder.\n * @notice Method is not a required method to allow Recipients to trust multiple Forwarders. Not recommended yet.\n * @return forwarder The address of the Forwarder contract that is being used.\n */\n function getTrustedForwarder() public virtual view returns (address forwarder){\n return _trustedForwarder;\n }\n\n function _setTrustedForwarder(address _forwarder) internal {\n _trustedForwarder = _forwarder;\n }\n\n /// @inheritdoc IERC2771Recipient\n function isTrustedForwarder(address forwarder) public virtual override view returns(bool) {\n return forwarder == _trustedForwarder;\n }\n\n /// @inheritdoc IERC2771Recipient\n function _msgSender() internal override virtual view returns (address ret) {\n if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // so we trust that the last bytes of msg.data are the verified sender address.\n // extract sender address from the end of msg.data\n assembly {\n ret := shr(96,calldataload(sub(calldatasize(),20)))\n }\n } else {\n ret = msg.sender;\n }\n }\n\n /// @inheritdoc IERC2771Recipient\n function _msgData() internal override virtual view returns (bytes calldata ret) {\n if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) {\n return msg.data[0:msg.data.length-20];\n } else {\n return msg.data;\n }\n }\n}" + }, + "contracts-link/forwarder/Forwarder.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// solhint-disable not-rely-on-time\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\nimport \"./IForwarder.sol\";\n\n/**\n * @title The Forwarder Implementation\n * @notice This implementation of the `IForwarder` interface uses ERC-712 signatures and stored nonces for verification.\n */\ncontract Forwarder is IForwarder, ERC165 {\n using ECDSA for bytes32;\n\n address private constant DRY_RUN_ADDRESS = 0x0000000000000000000000000000000000000000;\n\n string public constant GENERIC_PARAMS = \"address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data,uint256 validUntilTime\";\n\n string public constant EIP712_DOMAIN_TYPE = \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\";\n\n mapping(bytes32 => bool) public typeHashes;\n mapping(bytes32 => bool) public domains;\n\n // Nonces of senders, used to prevent replay attacks\n mapping(address => uint256) private nonces;\n\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n\n /// @inheritdoc IForwarder\n function getNonce(address from)\n public view override\n returns (uint256) {\n return nonces[from];\n }\n\n constructor() {\n string memory requestType = string(abi.encodePacked(\"ForwardRequest(\", GENERIC_PARAMS, \")\"));\n registerRequestTypeInternal(requestType);\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n return interfaceId == type(IForwarder).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IForwarder\n function verify(\n ForwardRequest calldata req,\n bytes32 domainSeparator,\n bytes32 requestTypeHash,\n bytes calldata suffixData,\n bytes calldata sig)\n external override view {\n _verifyNonce(req);\n _verifySig(req, domainSeparator, requestTypeHash, suffixData, sig);\n }\n\n /// @inheritdoc IForwarder\n function execute(\n ForwardRequest calldata req,\n bytes32 domainSeparator,\n bytes32 requestTypeHash,\n bytes calldata suffixData,\n bytes calldata sig\n )\n external payable\n override\n returns (bool success, bytes memory ret) {\n _verifySig(req, domainSeparator, requestTypeHash, suffixData, sig);\n _verifyAndUpdateNonce(req);\n\n require(req.validUntilTime == 0 || req.validUntilTime > block.timestamp, \"FWD: request expired\");\n\n uint256 gasForTransfer = 0;\n if ( req.value != 0 ) {\n gasForTransfer = 40000; //buffer in case we need to move eth after the transaction.\n }\n bytes memory callData = abi.encodePacked(req.data, req.from);\n require(gasleft()*63/64 >= req.gas + gasForTransfer, \"FWD: insufficient gas\");\n // solhint-disable-next-line avoid-low-level-calls\n (success,ret) = req.to.call{gas : req.gas, value : req.value}(callData);\n\n if ( req.value != 0 && address(this).balance>0 ) {\n // can't fail: req.from signed (off-chain) the request, so it must be an EOA...\n payable(req.from).transfer(address(this).balance);\n }\n\n return (success,ret);\n }\n\n function _verifyNonce(ForwardRequest calldata req) internal view {\n require(nonces[req.from] == req.nonce, \"FWD: nonce mismatch\");\n }\n\n function _verifyAndUpdateNonce(ForwardRequest calldata req) internal {\n require(nonces[req.from]++ == req.nonce, \"FWD: nonce mismatch\");\n }\n\n /// @inheritdoc IForwarder\n function registerRequestType(string calldata typeName, string calldata typeSuffix) external override {\n\n for (uint256 i = 0; i < bytes(typeName).length; i++) {\n bytes1 c = bytes(typeName)[i];\n require(c != \"(\" && c != \")\", \"FWD: invalid typename\");\n }\n\n string memory requestType = string(abi.encodePacked(typeName, \"(\", GENERIC_PARAMS, \",\", typeSuffix));\n registerRequestTypeInternal(requestType);\n }\n\n /// @inheritdoc IForwarder\n function registerDomainSeparator(string calldata name, string calldata version) external override {\n uint256 chainId;\n /* solhint-disable-next-line no-inline-assembly */\n assembly { chainId := chainid() }\n\n bytes memory domainValue = abi.encode(\n keccak256(bytes(EIP712_DOMAIN_TYPE)),\n keccak256(bytes(name)),\n keccak256(bytes(version)),\n chainId,\n address(this));\n\n bytes32 domainHash = keccak256(domainValue);\n\n domains[domainHash] = true;\n emit DomainRegistered(domainHash, domainValue);\n }\n\n function registerRequestTypeInternal(string memory requestType) internal {\n\n bytes32 requestTypehash = keccak256(bytes(requestType));\n typeHashes[requestTypehash] = true;\n emit RequestTypeRegistered(requestTypehash, requestType);\n }\n\n function _verifySig(\n ForwardRequest calldata req,\n bytes32 domainSeparator,\n bytes32 requestTypeHash,\n bytes calldata suffixData,\n bytes calldata sig)\n internal\n virtual\n view\n {\n require(domains[domainSeparator], \"FWD: unregistered domain sep.\");\n require(typeHashes[requestTypeHash], \"FWD: unregistered typehash\");\n bytes32 digest = keccak256(abi.encodePacked(\n \"\\x19\\x01\", domainSeparator,\n keccak256(_getEncoded(req, requestTypeHash, suffixData))\n ));\n // solhint-disable-next-line avoid-tx-origin\n require(tx.origin == DRY_RUN_ADDRESS || digest.recover(sig) == req.from, \"FWD: signature mismatch\");\n }\n\n /**\n * @notice Creates a byte array that is a valid ABI encoding of a request of a `RequestType` type. See `execute()`.\n */\n function _getEncoded(\n ForwardRequest calldata req,\n bytes32 requestTypeHash,\n bytes calldata suffixData\n )\n public\n pure\n returns (\n bytes memory\n ) {\n // we use encodePacked since we append suffixData as-is, not as dynamic param.\n // still, we must make sure all first params are encoded as abi.encode()\n // would encode them - as 256-bit-wide params.\n return abi.encodePacked(\n requestTypeHash,\n uint256(uint160(req.from)),\n uint256(uint160(req.to)),\n req.value,\n req.gas,\n req.nonce,\n keccak256(req.data),\n req.validUntilTime,\n suffixData\n );\n }\n}" + }, + "contracts-link/forwarder/IForwarder.sol": { + "content": "pragma solidity >=0.7.6;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"@openzeppelin/contracts/interfaces/IERC165.sol\";\n\n/**\n * @title The Forwarder Interface\n * @notice The contracts implementing this interface take a role of authorization, authentication and replay protection\n * for contracts that choose to trust a `Forwarder`, instead of relying on a mechanism built into the Ethereum protocol.\n *\n * @notice if the `Forwarder` contract decides that an incoming `ForwardRequest` is valid, it must append 20 bytes that\n * represent the caller to the `data` field of the request and send this new data to the target address (the `to` field)\n *\n * :warning: **Warning** :warning: The Forwarder can have a full control over a `Recipient` contract.\n * Any vulnerability in a `Forwarder` implementation can make all of its `Recipient` contracts susceptible!\n * Recipient contracts should only trust forwarders that passed through security audit,\n * otherwise they are susceptible to identity theft.\n */\ninterface IForwarder is IERC165 {\n\n /**\n * @notice A representation of a request for a `Forwarder` to send `data` on behalf of a `from` to a target (`to`).\n */\n struct ForwardRequest {\n address from;\n address to;\n uint256 value;\n uint256 gas;\n uint256 nonce;\n bytes data;\n uint256 validUntilTime;\n }\n\n event DomainRegistered(bytes32 indexed domainSeparator, bytes domainValue);\n\n event RequestTypeRegistered(bytes32 indexed typeHash, string typeStr);\n\n /**\n * @param from The address of a sender.\n * @return The nonce for this address.\n */\n function getNonce(address from)\n external view\n returns(uint256);\n\n /**\n * @notice Verify the transaction is valid and can be executed.\n * Implementations must validate the signature and the nonce of the request are correct.\n * Does not revert and returns successfully if the input is valid.\n * Reverts if any validation has failed. For instance, if either signature or nonce are incorrect.\n * Reverts if `domainSeparator` or `requestTypeHash` are not registered as well.\n */\n function verify(\n ForwardRequest calldata forwardRequest,\n bytes32 domainSeparator,\n bytes32 requestTypeHash,\n bytes calldata suffixData,\n bytes calldata signature\n ) external view;\n\n /**\n * @notice Executes a transaction specified by the `ForwardRequest`.\n * The transaction is first verified and then executed.\n * The success flag and returned bytes array of the `CALL` are returned as-is.\n *\n * This method would revert only in case of a verification error.\n *\n * All the target errors are reported using the returned success flag and returned bytes array.\n *\n * @param forwardRequest All requested transaction parameters.\n * @param domainSeparator The domain used when signing this request.\n * @param requestTypeHash The request type used when signing this request.\n * @param suffixData The ABI-encoded extension data for the current `RequestType` used when signing this request.\n * @param signature The client signature to be validated.\n *\n * @return success The success flag of the underlying `CALL` to the target address.\n * @return ret The byte array returned by the underlying `CALL` to the target address.\n */\n function execute(\n ForwardRequest calldata forwardRequest,\n bytes32 domainSeparator,\n bytes32 requestTypeHash,\n bytes calldata suffixData,\n bytes calldata signature\n )\n external payable\n returns (bool success, bytes memory ret);\n\n /**\n * @notice Register a new Request typehash.\n *\n * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\n *\n * @param typeName The name of the request type.\n * @param typeSuffix Any extra data after the generic params. Must contain add at least one param.\n * The generic ForwardRequest type is always registered by the constructor.\n */\n function registerRequestType(string calldata typeName, string calldata typeSuffix) external;\n\n /**\n * @notice Register a new domain separator.\n *\n * @notice This is necessary for the Forwarder to be able to verify the signatures conforming to the ERC-712.\n *\n * @notice The domain separator must have the following fields: `name`, `version`, `chainId`, `verifyingContract`.\n * The `chainId` is the current network's `chainId`, and the `verifyingContract` is this Forwarder's address.\n * This method accepts the domain name and version to create and register the domain separator value.\n * @param name The domain's display name.\n * @param version The domain/protocol version.\n */\n function registerDomainSeparator(string calldata name, string calldata version) external;\n}" + }, + "contracts-link/forwarder/test/TestForwarder.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../Forwarder.sol\";\n\n// helper class for testing the forwarder.\ncontract TestForwarder {\n function callExecute(Forwarder forwarder, Forwarder.ForwardRequest memory req,\n bytes32 domainSeparator, bytes32 requestTypeHash, bytes memory suffixData, bytes memory sig) public payable {\n (bool success, bytes memory error) = forwarder.execute{value:msg.value}(req, domainSeparator, requestTypeHash, suffixData, sig);\n emit Result(success, success ? \"\" : this.decodeErrorMessage(error));\n }\n\n event Result(bool success, string error);\n\n function decodeErrorMessage(bytes calldata ret) external pure returns (string memory message) {\n //decode evert string: assume it has a standard Error(string) signature: simply skip the (selector,offset,length) fields\n if ( ret.length>4+32+32 ) {\n return abi.decode(ret[4:], (string));\n }\n //unknown buffer. return as-is\n return string(ret);\n }\n\n function getChainId() public view returns (uint256 id){\n /* solhint-disable-next-line no-inline-assembly */\n assembly { id := chainid() }\n }\n}" + }, + "contracts-link/forwarder/test/TestForwarderTarget.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../../ERC2771Recipient.sol\";\n\ncontract TestForwarderTarget is ERC2771Recipient {\n\n constructor(address forwarder) {\n _setTrustedForwarder(forwarder);\n }\n\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n\n event TestForwarderMessage(string message, bytes realMsgData, address realSender, address msgSender, address origin);\n\n function emitMessage(string memory message) public {\n\n // solhint-disable-next-line avoid-tx-origin\n emit TestForwarderMessage(message, _msgData(), _msgSender(), msg.sender, tx.origin);\n }\n\n function publicMsgSender() public view returns (address) {\n return _msgSender();\n }\n\n function publicMsgData() public view returns (bytes memory) {\n return _msgData();\n }\n\n function mustReceiveEth(uint256 value) public payable {\n require( msg.value == value, \"didn't receive value\");\n }\n\n event Reverting(string message);\n\n function testRevert() public {\n require(address(this) == address(0), \"always fail\");\n emit Reverting(\"if you see this revert failed...\");\n }\n}" + }, + "contracts-link/interfaces/IERC20Token.sol": { + "content": "pragma solidity >=0.7.6;\n\n// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\n/**\n * @notice Extended ERC-20 token interface used internally in OpenGSN modules.\n * Renamed to avoid conflict with OZ namespace. Includes IERC20, ERC20Metadata.\n * added semi-standard \"wrapped eth\" access methods deposit() and \"withdraw()\"\n */\ninterface IERC20Token is IERC20, IERC20Metadata {\n\n function deposit() external payable;\n function withdraw(uint256 amount) external;\n}" + }, + "contracts-link/interfaces/IERC2771Recipient.sol": { + "content": "pragma solidity >=0.6.0;\n\n// SPDX-License-Identifier: MIT\n\n/**\n * @title The ERC-2771 Recipient Base Abstract Class - Declarations\n *\n * @notice A contract must implement this interface in order to support relayed transaction.\n *\n * @notice It is recommended that your contract inherits from the ERC2771Recipient contract.\n */\nabstract contract IERC2771Recipient {\n\n /**\n * :warning: **Warning** :warning: The Forwarder can have a full control over your Recipient. Only trust verified Forwarder.\n * @param forwarder The address of the Forwarder contract that is being used.\n * @return isTrustedForwarder `true` if the Forwarder is trusted to forward relayed transactions by this Recipient.\n */\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\n\n /**\n * @notice Use this method the contract anywhere instead of msg.sender to support relayed transactions.\n * @return sender The real sender of this call.\n * For a call that came through the Forwarder the real sender is extracted from the last 20 bytes of the `msg.data`.\n * Otherwise simply returns `msg.sender`.\n */\n function _msgSender() internal virtual view returns (address);\n\n /**\n * @notice Use this method in the contract instead of `msg.data` when difference matters (hashing, signature, etc.)\n * @return data The real `msg.data` of this call.\n * For a call that came through the Forwarder, the real sender address was appended as the last 20 bytes\n * of the `msg.data` - so this method will strip those 20 bytes off.\n * Otherwise (if the call was made directly and not through the forwarder) simply returns `msg.data`.\n */\n function _msgData() internal virtual view returns (bytes calldata);\n}" + }, + "contracts-link/interfaces/IPaymaster.sol": { + "content": "pragma solidity >=0.7.6;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"@openzeppelin/contracts/interfaces/IERC165.sol\";\n\nimport \"../utils/GsnTypes.sol\";\n\n/**\n * @title The Paymaster Interface\n * @notice Contracts implementing this interface exist to make decision about paying the transaction fee to the relay.\n *\n * @notice There are two callbacks here that are executed by the RelayHub: `preRelayedCall` and `postRelayedCall`.\n *\n * @notice It is recommended that your implementation inherits from the abstract BasePaymaster contract.\n*/\ninterface IPaymaster is IERC165 {\n /**\n * @notice The limits this Paymaster wants to be imposed by the RelayHub on user input. See `getGasAndDataLimits`.\n */\n struct GasAndDataLimits {\n uint256 acceptanceBudget;\n uint256 preRelayedCallGasLimit;\n uint256 postRelayedCallGasLimit;\n uint256 calldataSizeLimit;\n }\n\n /**\n * @notice Return the Gas Limits for Paymaster's functions and maximum msg.data length values for this Paymaster.\n * This function allows different paymasters to have different properties without changes to the RelayHub.\n * @return limits An instance of the `GasAndDataLimits` struct\n *\n * ##### `acceptanceBudget`\n * If the transactions consumes more than `acceptanceBudget` this Paymaster will be charged for gas no matter what.\n * Transaction that gets rejected after consuming more than `acceptanceBudget` gas is on this Paymaster's expense.\n *\n * Should be set to an amount gas this Paymaster expects to spend deciding whether to accept or reject a request.\n * This includes gas consumed by calculations in the `preRelayedCall`, `Forwarder` and the recipient contract.\n *\n * :warning: **Warning** :warning: As long this value is above `preRelayedCallGasLimit`\n * (see defaults in `BasePaymaster`), the Paymaster is guaranteed it will never pay for rejected transactions.\n * If this value is below `preRelayedCallGasLimit`, it might might make Paymaster open to a \"griefing\" attack.\n *\n * The relayers should prefer lower `acceptanceBudget`, as it improves their chances of being compensated.\n * From a Relay's point of view, this is the highest gas value a bad Paymaster may cost the relay,\n * since the paymaster will pay anything above that value regardless of whether the transaction succeeds or reverts.\n * Specifying value too high might make the call rejected by relayers (see `maxAcceptanceBudget` in server config).\n *\n * ##### `preRelayedCallGasLimit`\n * The max gas usage of preRelayedCall. Any revert of the `preRelayedCall` is a request rejection by the paymaster.\n * As long as `acceptanceBudget` is above `preRelayedCallGasLimit`, any such revert is not payed by the paymaster.\n *\n * ##### `postRelayedCallGasLimit`\n * The max gas usage of postRelayedCall. The Paymaster is not charged for the maximum, only for actually used gas.\n * Note that an OOG will revert the inner transaction, but the paymaster will be charged for it anyway.\n */\n function getGasAndDataLimits()\n external\n view\n returns (\n GasAndDataLimits memory limits\n );\n\n /**\n * @notice :warning: **Warning** :warning: using incorrect Forwarder may cause the Paymaster to agreeing to pay for invalid transactions.\n * @return trustedForwarder The address of the `Forwarder` that is trusted by this Paymaster to execute the requests.\n */\n function getTrustedForwarder() external view returns (address trustedForwarder);\n\n /**\n * @return relayHub The address of the `RelayHub` that is trusted by this Paymaster to execute the requests.\n */\n function getRelayHub() external view returns (address relayHub);\n\n /**\n * @notice Called by the Relay in view mode and later by the `RelayHub` on-chain to validate that\n * the Paymaster agrees to pay for this call.\n *\n * The request is considered to be rejected by the Paymaster in one of the following conditions:\n * - `preRelayedCall()` method reverts\n * - the `Forwarder` reverts because of nonce or signature error\n * - the `Paymaster` returned `rejectOnRecipientRevert: true` and the recipient contract reverted\n * (and all that did not consume more than `acceptanceBudget` gas).\n *\n * In any of the above cases, all Paymaster calls and the recipient call are reverted.\n * In any other case the Paymaster will pay for the gas cost of the transaction.\n * Note that even if `postRelayedCall` is reverted the Paymaster will be charged.\n *\n\n * @param relayRequest - the full relay request structure\n * @param signature - user's EIP712-compatible signature of the `relayRequest`.\n * Note that in most cases the paymaster shouldn't try use it at all. It is always checked\n * by the forwarder immediately after preRelayedCall returns.\n * @param approvalData - extra dapp-specific data (e.g. signature from trusted party)\n * @param maxPossibleGas - based on values returned from `getGasAndDataLimits`\n * the RelayHub will calculate the maximum possible amount of gas the user may be charged for.\n * In order to convert this value to wei, the Paymaster has to call \"relayHub.calculateCharge()\"\n *\n * @return context\n * A byte array to be passed to postRelayedCall.\n * Can contain any data needed by this Paymaster in any form or be empty if no extra data is needed.\n * @return rejectOnRecipientRevert\n * The flag that allows a Paymaster to \"delegate\" the rejection to the recipient code.\n * It also means the Paymaster trust the recipient to reject fast: both preRelayedCall,\n * forwarder check and recipient checks must fit into the GasLimits.acceptanceBudget,\n * otherwise the TX is paid by the Paymaster.\n * `true` if the Paymaster wants to reject the TX if the recipient reverts.\n * `false` if the Paymaster wants rejects by the recipient to be completed on chain and paid by the Paymaster.\n */\n function preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n external\n returns (bytes memory context, bool rejectOnRecipientRevert);\n\n /**\n * @notice This method is called after the actual relayed function call.\n * It may be used to record the transaction (e.g. charge the caller by some contract logic) for this call.\n *\n * Revert in this functions causes a revert of the client's relayed call (and preRelayedCall(), but the Paymaster\n * is still committed to pay the relay for the entire transaction.\n *\n * @param context The call context, as returned by the preRelayedCall\n * @param success `true` if the relayed call succeeded, false if it reverted\n * @param gasUseWithoutPost The actual amount of gas used by the entire transaction, EXCEPT\n * the gas used by the postRelayedCall itself.\n * @param relayData The relay params of the request. can be used by relayHub.calculateCharge()\n *\n */\n function postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n ) external;\n\n /**\n * @return version The SemVer string of this Paymaster's version.\n */\n function versionPaymaster() external view returns (string memory);\n}" + }, + "contracts-link/interfaces/IPenalizer.sol": { + "content": "pragma solidity >=0.7.6;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"./IRelayHub.sol\";\n\n/**\n * @title The Penalizer Interface\n * @notice In some cases the behavior of a Relay Server may be found to be illegal.\n * It is the responsibility of a `Penalizer` contract to judge whether there was a penalizable event.\n *\n * @notice In case there was, the `Penalizer` will direct the `RelayHub` to slash the stake of the faulty Relay Server.\n */\ninterface IPenalizer is IERC165 {\n\n /// @notice Emitted once the reporter submits the first step in the commit-reveal process.\n event CommitAdded(address indexed sender, bytes32 indexed commitHash, uint256 readyBlockNumber);\n\n struct Transaction {\n uint256 nonce;\n uint256 gasLimit;\n address to;\n uint256 value;\n bytes data;\n }\n\n /**\n * @notice Called by the reporter as the first step in the commit-reveal process.\n * Any sender can call it to make sure no-one can front-run it to claim this penalization.\n * @param commitHash The hash of the report of a penalizable behaviour the reporter wants to reveal.\n * Calculated as `commit(keccak(encodedPenalizeFunction))`.\n */\n function commit(bytes32 commitHash) external;\n\n /**\n * @notice Called by the reporter as the second step in the commit-reveal process.\n * If a Relay Worker attacked the system by signing multiple transactions with same nonce so only one is accepted,\n * anyone can grab both transactions from the blockchain and submit them here.\n * Check whether `unsignedTx1` != `unsignedTx2`, that both are signed by the same address,\n * and that `unsignedTx1.nonce` == `unsignedTx2.nonce`.\n * If all conditions are met, relay is considered an \"offending relay\".\n * The offending relay will be unregistered immediately, its stake will be forfeited and given\n * to the address who reported it (the `msg.sender`), thus incentivizing anyone to report offending relays.\n */\n function penalizeRepeatedNonce(\n bytes calldata unsignedTx1,\n bytes calldata signature1,\n bytes calldata unsignedTx2,\n bytes calldata signature2,\n IRelayHub hub,\n uint256 randomValue\n ) external;\n\n /**\n * @notice Called by the reporter as the second step in the commit-reveal process.\n * The Relay Workers are not allowed to make calls other than to the `relayCall` method.\n */\n function penalizeIllegalTransaction(\n bytes calldata unsignedTx,\n bytes calldata signature,\n IRelayHub hub,\n uint256 randomValue\n ) external;\n\n /// @return a SemVer-compliant version of the `Penalizer` contract.\n function versionPenalizer() external view returns (string memory);\n\n /// @return The minimum delay between commit and reveal steps.\n function getPenalizeBlockDelay() external view returns (uint256);\n\n /// @return The maximum delay between commit and reveal steps.\n function getPenalizeBlockExpiration() external view returns (uint256);\n}" + }, + "contracts-link/interfaces/IRelayHub.sol": { + "content": "pragma solidity >=0.7.6;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"@openzeppelin/contracts/interfaces/IERC165.sol\";\n\nimport \"../utils/GsnTypes.sol\";\nimport \"./IStakeManager.sol\";\n\n/**\n * @title The RelayHub interface\n * @notice The implementation of this interface provides all the information the GSN client needs to\n * create a valid `RelayRequest` and also serves as an entry point for such requests.\n *\n * @notice The RelayHub also handles all the related financial records and hold the balances of participants.\n * The Paymasters keep their Ether deposited in the `RelayHub` in order to pay for the `RelayRequest`s that thay choose\n * to pay for, and Relay Servers keep their earned Ether in the `RelayHub` until they choose to `withdraw()`\n *\n * @notice The RelayHub on each supported network only needs a single instance and there is usually no need for dApp\n * developers or Relay Server operators to redeploy, reimplement, modify or override the `RelayHub`.\n */\ninterface IRelayHub is IERC165 {\n /**\n * @notice A struct that contains all the parameters of the `RelayHub` that can be modified after the deployment.\n */\n struct RelayHubConfig {\n // maximum number of worker accounts allowed per manager\n uint256 maxWorkerCount;\n // Gas set aside for all relayCall() instructions to prevent unexpected out-of-gas exceptions\n uint256 gasReserve;\n // Gas overhead to calculate gasUseWithoutPost\n uint256 postOverhead;\n // Gas cost of all relayCall() instructions after actual 'calculateCharge()'\n // Assume that relay has non-zero balance (costs 15'000 more otherwise).\n uint256 gasOverhead;\n // Minimum unstake delay seconds of a relay manager's stake on the StakeManager\n uint256 minimumUnstakeDelay;\n // Developers address\n address devAddress;\n // 0 < fee < 100, as percentage of total charge from paymaster to relayer\n uint8 devFee;\n // baseRelayFee The base fee the Relay Server charges for a single transaction in Ether, in wei.\n uint80 baseRelayFee;\n // pctRelayFee The percent of the total charge to add as a Relay Server fee to the total charge.\n uint16 pctRelayFee;\n }\n\n /// @notice Emitted when a configuration of the `RelayHub` is changed\n event RelayHubConfigured(RelayHubConfig config);\n\n /// @notice Emitted when relays are added by a relayManager\n event RelayWorkersAdded(\n address indexed relayManager,\n address[] newRelayWorkers,\n uint256 workersCount\n );\n\n /// @notice Emitted when an account withdraws funds from the `RelayHub`.\n event Withdrawn(\n address indexed account,\n address indexed dest,\n uint256 amount\n );\n\n /// @notice Emitted when `depositFor` is called, including the amount and account that was funded.\n event Deposited(\n address indexed paymaster,\n address indexed from,\n uint256 amount\n );\n\n /// @notice Emitted for each token configured for staking in setMinimumStakes\n event StakingTokenDataChanged(\n address token,\n uint256 minimumStake\n );\n\n /**\n * @notice Emitted when an attempt to relay a call fails and the `Paymaster` does not accept the transaction.\n * The actual relayed call was not executed, and the recipient not charged.\n * @param reason contains a revert reason returned from preRelayedCall or forwarder.\n */\n event TransactionRejectedByPaymaster(\n address indexed relayManager,\n address indexed paymaster,\n bytes32 indexed relayRequestID,\n address from,\n address to,\n address relayWorker,\n bytes4 selector,\n uint256 innerGasUsed,\n bytes reason\n );\n\n /**\n * @notice Emitted when a transaction is relayed. Note that the actual internal function call might be reverted.\n * The reason for a revert will be indicated in the `status` field of a corresponding `RelayCallStatus` value.\n * @notice `charge` is the Ether value deducted from the `Paymaster` balance.\n * The amount added to the `relayManager` balance will be lower if there is an activated `devFee` in the `config`.\n */\n event TransactionRelayed(\n address indexed relayManager,\n address indexed relayWorker,\n bytes32 indexed relayRequestID,\n address from,\n address to,\n address paymaster,\n bytes4 selector,\n RelayCallStatus status,\n uint256 charge\n );\n\n /// @notice This event is emitted in case the internal function returns a value or reverts with a revert string.\n event TransactionResult(\n RelayCallStatus status,\n bytes returnValue\n );\n\n /// @notice This event is emitted in case this `RelayHub` is deprecated and will stop serving transactions soon.\n event HubDeprecated(uint256 deprecationTime);\n\n /**\n * @notice This event is emitted in case a `relayManager` has been deemed \"abandoned\" for being\n * unresponsive for a prolonged period of time.\n * @notice This event means the entire balance of the relay has been transferred to the `devAddress`.\n */\n event AbandonedRelayManagerBalanceEscheated(\n address indexed relayManager,\n uint256 balance\n );\n\n /**\n * Error codes that describe all possible failure reasons reported in the `TransactionRelayed` event `status` field.\n * @param OK The transaction was successfully relayed and execution successful - never included in the event.\n * @param RelayedCallFailed The transaction was relayed, but the relayed call failed.\n * @param RejectedByPreRelayed The transaction was not relayed due to preRelatedCall reverting.\n * @param RejectedByForwarder The transaction was not relayed due to forwarder check (signature,nonce).\n * @param PostRelayedFailed The transaction was relayed and reverted due to postRelatedCall reverting.\n * @param PaymasterBalanceChanged The transaction was relayed and reverted due to the paymaster balance change.\n */\n enum RelayCallStatus {\n OK,\n RelayedCallFailed,\n RejectedByPreRelayed,\n RejectedByForwarder,\n RejectedByRecipientRevert,\n PostRelayedFailed,\n PaymasterBalanceChanged\n }\n\n /**\n * @notice Add new worker addresses controlled by the sender who must be a staked Relay Manager address.\n * Emits a `RelayWorkersAdded` event.\n * This function can be called multiple times, emitting new events.\n */\n function addRelayWorkers(address[] calldata newRelayWorkers) external;\n\n /**\n * @notice The `RelayRegistrar` callback to notify the `RelayHub` that this `relayManager` has updated registration.\n */\n function onRelayServerRegistered(address relayManager) external;\n\n // Balance management\n\n /**\n * @notice Deposits ether for a `Paymaster`, so that it can and pay for relayed transactions.\n * :warning: **Warning** :warning: Unused balance can only be withdrawn by the holder itself, by calling `withdraw`.\n * Emits a `Deposited` event.\n */\n function depositFor(address target) external payable;\n\n /**\n * @notice Withdraws from an account's balance, sending it back to the caller.\n * Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding.\n * Emits a `Withdrawn` event.\n */\n function withdraw(address payable dest, uint256 amount) external;\n\n /**\n * @notice Withdraws from an account's balance, sending funds to multiple provided addresses.\n * Relay Managers call this to retrieve their revenue, and `Paymasters` can also use it to reduce their funding.\n * Emits a `Withdrawn` event for each destination.\n */\n function withdrawMultiple(address payable[] memory dest, uint256[] memory amount) external;\n\n // Relaying\n\n /**\n * @notice Relays a transaction. For this to succeed, multiple conditions must be met:\n * - `Paymaster`'s `preRelayCall` method must succeed and not revert.\n * - the `msg.sender` must be a registered Relay Worker that the user signed to use.\n * - the transaction's gas fees must be equal or larger than the ones that were signed by the sender.\n * - the transaction must have enough gas to run all internal transactions if they use all gas available to them.\n * - the `Paymaster` must have enough balance to pay the Relay Worker if all gas is spent.\n *\n * @notice If all conditions are met, the call will be relayed and the `Paymaster` charged.\n *\n * @param domainSeparatorName The name of the Domain Separator used to verify the EIP-712 signature\n * @param maxAcceptanceBudget The maximum valid value for `paymaster.getGasLimits().acceptanceBudget` to return.\n * @param relayRequest All details of the requested relayed call.\n * @param signature The client's EIP-712 signature over the `relayRequest` struct.\n * @param approvalData The dapp-specific data forwarded to the `Paymaster`'s `preRelayedCall` method.\n * This value is **not** verified by the `RelayHub` in any way.\n * As an example, it can be used to pass some kind of a third-party signature to the `Paymaster` for verification.\n *\n * Emits a `TransactionRelayed` event regardless of whether the transaction succeeded or failed.\n */\n function relayCall(\n string calldata domainSeparatorName,\n uint256 maxAcceptanceBudget,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData\n )\n external\n returns (\n bool paymasterAccepted,\n uint256 charge,\n IRelayHub.RelayCallStatus status,\n bytes memory returnValue\n );\n\n /**\n * @notice In case the Relay Worker has been found to be in violation of some rules by the `Penalizer` contract,\n * the `Penalizer` will call this method to execute a penalization.\n * The `RelayHub` will look up the Relay Manager of the given Relay Worker and will forward the call to\n * the `StakeManager` contract. The `RelayHub` does not perform the actual penalization either.\n * @param relayWorker The address of the Relay Worker that committed a penalizable offense.\n * @param beneficiary The address that called the `Penalizer` and will receive a reward for it.\n */\n function penalize(address relayWorker, address payable beneficiary) external;\n\n /**\n * @notice Sets or changes the configuration of this `RelayHub`.\n * @param _config The new configuration.\n */\n function setConfiguration(RelayHubConfig memory _config) external;\n\n /**\n * @notice Sets or changes the minimum amount of a given `token` that needs to be staked so that the Relay Manager\n * is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.\n * @param token An array of addresses of ERC-20 compatible tokens.\n * @param minimumStake An array of minimal amounts necessary for a corresponding token, in wei.\n */\n function setMinimumStakes(IERC20[] memory token, uint256[] memory minimumStake) external;\n\n /**\n * @notice Deprecate hub by reverting all incoming `relayCall()` calls starting from a given timestamp\n * @param _deprecationTime The timestamp in seconds after which the `RelayHub` stops serving transactions.\n */\n function deprecateHub(uint256 _deprecationTime) external;\n\n /**\n * @notice\n * @param relayManager\n */\n function escheatAbandonedRelayBalance(address relayManager) external;\n\n /**\n * @notice The fee is expressed as a base fee in wei plus percentage of the actual charge.\n * For example, a value '40' stands for a 40% fee, so the recipient will be charged for 1.4 times the spent amount.\n * @param gasUsed An amount of gas used by the transaction.\n * @param relayData The details of a transaction signed by the sender.\n * @return The calculated charge, in wei.\n */\n function calculateCharge(uint256 gasUsed, GsnTypes.RelayData calldata relayData) external view returns (uint256);\n\n /**\n * @notice The fee is expressed as a percentage of the actual charge.\n * For example, a value '40' stands for a 40% fee, so the Relay Manager will only get 60% of the `charge`.\n * @param charge The amount of Ether in wei the Paymaster will be charged for this transaction.\n * @return The calculated devFee, in wei.\n */\n function calculateDevCharge(uint256 charge) external view returns (uint256);\n /* getters */\n\n /// @return config The configuration of the `RelayHub`.\n function getConfiguration() external view returns (RelayHubConfig memory config);\n\n /**\n * @param token An address of an ERC-20 compatible tokens.\n * @return The minimum amount of a given `token` that needs to be staked so that the Relay Manager\n * is considered to be 'staked' by this `RelayHub`. Zero value means this token is not allowed for staking.\n */\n function getMinimumStakePerToken(IERC20 token) external view returns (uint256);\n\n /**\n * @param worker An address of the Relay Worker.\n * @return The address of its Relay Manager.\n */\n function getWorkerManager(address worker) external view returns (address);\n\n /**\n * @param manager An address of the Relay Manager.\n * @return The count of Relay Workers associated with this Relay Manager.\n */\n function getWorkerCount(address manager) external view returns (uint256);\n\n /// @return An account's balance. It can be either a deposit of a `Paymaster`, or a revenue of a Relay Manager.\n function balanceOf(address target) external view returns (uint256);\n\n /// @return The `StakeManager` address for this `RelayHub`.\n function getStakeManager() external view returns (IStakeManager);\n\n /// @return The `Penalizer` address for this `RelayHub`.\n function getPenalizer() external view returns (address);\n\n /// @return The `RelayRegistrar` address for this `RelayHub`.\n function getRelayRegistrar() external view returns (address);\n\n /// @return The `BatchGateway` address for this `RelayHub`.\n function getBatchGateway() external view returns (address);\n\n /**\n * @notice Uses `StakeManager` to decide if the Relay Manager can be considered staked or not.\n * Returns if the stake's token, amount and delay satisfy all requirements, reverts otherwise.\n */\n function verifyRelayManagerStaked(address relayManager) external view;\n\n /**\n * @notice Uses `StakeManager` to check if the Relay Manager can be considered abandoned or not.\n * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\n */\n function isRelayEscheatable(address relayManager) external view returns (bool);\n\n /// @return `true` if the `RelayHub` is deprecated, `false` it it is not deprecated and can serve transactions.\n function isDeprecated() external view returns (bool);\n\n /// @return The timestamp from which the hub no longer allows relaying calls.\n function getDeprecationTime() external view returns (uint256);\n\n /// @return The block number in which the contract has been deployed.\n function getCreationBlock() external view returns (uint256);\n\n /// @return a SemVer-compliant version of the `RelayHub` contract.\n function versionHub() external view returns (string memory);\n\n /// @return A total measurable amount of gas left to current execution. Same as 'gasleft()' for pure EVMs.\n function aggregateGasleft() external view returns (uint256);\n}" + }, + "contracts-link/interfaces/IRelayRegistrar.sol": { + "content": "pragma solidity ^0.8.6;\n\n//SPDX-License-Identifier: GPL-3.0-only\n\nimport \"@openzeppelin/contracts/interfaces/IERC165.sol\";\n\n/**\n * @title The RelayRegistrar Interface\n * @notice The on-chain registrar for all registered Relay Managers.\n *\n * @notice The client can use an implementation of a `RelayRegistrar` to find relay registration info.\n *\n */\ninterface IRelayRegistrar is IERC165 {\n\n /**\n * @notice A struct containing all the information necessary to client to interact with the Relay Server.\n */\n struct RelayInfo {\n //last registration block number\n uint32 lastSeenBlockNumber;\n //last registration block timestamp\n uint40 lastSeenTimestamp;\n //stake (first registration) block number\n uint32 firstSeenBlockNumber;\n //stake (first registration) block timestamp\n uint40 firstSeenTimestamp;\n bytes32[3] urlParts;\n address relayManager;\n }\n\n /**\n * @notice Emitted when a relay server registers or updates its details.\n * Looking up these events allows a client to discover registered Relay Servers.\n */\n event RelayServerRegistered(\n address indexed relayManager,\n address indexed relayHub,\n bytes32[3] relayUrl\n );\n\n /**\n * @notice This function is called by Relay Servers in order to register or to update their registration.\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\n * @param url The URL of the Relay Server that is listening to the clients' requests.\n */\n function registerRelayServer(\n address relayHub,\n bytes32[3] calldata url\n ) external;\n\n /**\n * @return The block number in which the contract has been deployed.\n */\n function getCreationBlock() external view returns (uint256);\n\n /**\n * @return The maximum age the relay is considered registered by default by this `RelayRegistrar`, in seconds.\n */\n function getRelayRegistrationMaxAge() external view returns (uint256);\n\n /**\n * @notice Change the maximum relay registration age.\n */\n function setRelayRegistrationMaxAge(uint256) external;\n\n /**\n * @param relayManager An address of a Relay Manager.\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\n * @return info All the details of the given Relay Manager's registration. Throws if relay not found for `RelayHub`.\n */\n function getRelayInfo(address relayHub, address relayManager) external view returns (RelayInfo memory info);\n\n /**\n * @notice Read relay info of registered Relay Server from an on-chain storage.\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\n * @return info The list of `RelayInfo`s of registered Relay Servers\n */\n function readRelayInfos(\n address relayHub\n ) external view returns (\n RelayInfo[] memory info\n );\n\n /**\n * @notice Read relay info of registered Relay Server from an on-chain storage.\n * @param relayHub The address of the `RelayHub` contract for which this action is performed.\n * @param maxCount The maximum amount of relays to be returned by this function.\n * @param oldestBlockNumber The latest block number in which a Relay Server may be registered.\n * @param oldestBlockTimestamp The latest block timestamp in which a Relay Server may be registered.\n * @return info The list of `RelayInfo`s of registered Relay Servers\n */\n function readRelayInfosInRange(\n address relayHub,\n uint256 oldestBlockNumber,\n uint256 oldestBlockTimestamp,\n uint256 maxCount\n ) external view returns (\n RelayInfo[] memory info\n );\n}" + }, + "contracts-link/interfaces/IStakeManager.sol": { + "content": "pragma solidity >=0.7.6;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\n/**\n * @title The StakeManager Interface\n * @notice In order to prevent an attacker from registering a large number of unresponsive relays, the GSN requires\n * the Relay Server to maintain a permanently locked stake in the system before being able to register.\n *\n * @notice Also, in some cases the behavior of a Relay Server may be found to be illegal by a `Penalizer` contract.\n * In such case, the stake will never be returned to the Relay Server operator and will be slashed.\n *\n * @notice An implementation of this interface is tasked with keeping Relay Servers' stakes, made in any ERC-20 token.\n * Note that the `RelayHub` chooses which ERC-20 tokens to support and how much stake is needed.\n */\ninterface IStakeManager is IERC165 {\n\n /// @notice Emitted when a `stake` or `unstakeDelay` are initialized or increased.\n event StakeAdded(\n address indexed relayManager,\n address indexed owner,\n IERC20 token,\n uint256 stake,\n uint256 unstakeDelay\n );\n\n /// @notice Emitted once a stake is scheduled for withdrawal.\n event StakeUnlocked(\n address indexed relayManager,\n address indexed owner,\n uint256 withdrawTime\n );\n\n /// @notice Emitted when owner withdraws `relayManager` funds.\n event StakeWithdrawn(\n address indexed relayManager,\n address indexed owner,\n IERC20 token,\n uint256 amount\n );\n\n /// @notice Emitted when an authorized `RelayHub` penalizes a `relayManager`.\n event StakePenalized(\n address indexed relayManager,\n address indexed beneficiary,\n IERC20 token,\n uint256 reward\n );\n\n /// @notice Emitted when a `relayManager` adds a new `RelayHub` to a list of authorized.\n event HubAuthorized(\n address indexed relayManager,\n address indexed relayHub\n );\n\n /// @notice Emitted when a `relayManager` removes a `RelayHub` from a list of authorized.\n event HubUnauthorized(\n address indexed relayManager,\n address indexed relayHub,\n uint256 removalTime\n );\n\n /// @notice Emitted when a `relayManager` sets its `owner`. This is necessary to prevent stake hijacking.\n event OwnerSet(\n address indexed relayManager,\n address indexed owner\n );\n\n /// @notice Emitted when a `burnAddress` is changed.\n event BurnAddressSet(\n address indexed burnAddress\n );\n\n /// @notice Emitted when a `devAddress` is changed.\n event DevAddressSet(\n address indexed devAddress\n );\n\n /// @notice Emitted if Relay Server is inactive for an `abandonmentDelay` and contract owner initiates its removal.\n event RelayServerAbandoned(\n address indexed relayManager,\n uint256 abandonedTime\n );\n\n /// @notice Emitted to indicate an action performed by a relay server to prevent it from being marked as abandoned.\n event RelayServerKeepalive(\n address indexed relayManager,\n uint256 keepaliveTime\n );\n\n /// @notice Emitted when the stake of an abandoned relayer has been confiscated and transferred to the `devAddress`.\n event AbandonedRelayManagerStakeEscheated(\n address indexed relayManager,\n address indexed owner,\n IERC20 token,\n uint256 amount\n );\n\n /**\n * @param stake - amount of ether staked for this relay\n * @param unstakeDelay - number of seconds to elapse before the owner can retrieve the stake after calling 'unlock'\n * @param withdrawTime - timestamp in seconds when 'withdraw' will be callable, or zero if the unlock has not been called\n * @param owner - address that receives revenue and manages relayManager's stake\n */\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelay;\n uint256 withdrawTime;\n uint256 abandonedTime;\n uint256 keepaliveTime;\n IERC20 token;\n address owner;\n }\n\n struct RelayHubInfo {\n uint256 removalTime;\n }\n\n /**\n * @param devAddress - the address that will receive the 'abandoned' stake\n * @param abandonmentDelay - the amount of time after which the relay can be marked as 'abandoned'\n * @param escheatmentDelay - the amount of time after which the abandoned relay's stake and balance may be withdrawn to the `devAddress`\n */\n struct AbandonedRelayServerConfig {\n address devAddress;\n uint256 abandonmentDelay;\n uint256 escheatmentDelay;\n }\n\n /**\n * @notice Set the owner of a Relay Manager. Called only by the RelayManager itself.\n * Note that owners cannot transfer ownership - if the entry already exists, reverts.\n * @param owner - owner of the relay (as configured off-chain)\n */\n function setRelayManagerOwner(address owner) external;\n\n /**\n * @notice Put a stake for a relayManager and set its unstake delay.\n * Only the owner can call this function. If the entry does not exist, reverts.\n * The owner must give allowance of the ERC-20 token to the StakeManager before calling this method.\n * It is the RelayHub who has a configurable list of minimum stakes per token. StakeManager accepts all tokens.\n * @param token The address of an ERC-20 token that is used by the relayManager as a stake\n * @param relayManager The address that represents a stake entry and controls relay registrations on relay hubs\n * @param unstakeDelay The number of seconds to elapse before an owner can retrieve the stake after calling `unlock`\n * @param amount The amount of tokens to be taken from the relayOwner and locked in the StakeManager as a stake\n */\n function stakeForRelayManager(IERC20 token, address relayManager, uint256 unstakeDelay, uint256 amount) external;\n\n /**\n * @notice Schedule the unlocking of the stake. The `unstakeDelay` must pass before owner can call `withdrawStake`.\n * @param relayManager The address of a Relay Manager whose stake is to be unlocked.\n */\n function unlockStake(address relayManager) external;\n /**\n * @notice Withdraw the unlocked stake.\n * @param relayManager The address of a Relay Manager whose stake is to be withdrawn.\n */\n function withdrawStake(address relayManager) external;\n\n /**\n * @notice Add the `RelayHub` to a list of authorized by this Relay Manager.\n * This allows the RelayHub to penalize this Relay Manager. The `RelayHub` cannot trust a Relay it cannot penalize.\n * @param relayManager The address of a Relay Manager whose stake is to be authorized for the new `RelayHub`.\n * @param relayHub The address of a `RelayHub` to be authorized.\n */\n function authorizeHubByOwner(address relayManager, address relayHub) external;\n\n /**\n * @notice Same as `authorizeHubByOwner` but can be called by the RelayManager itself.\n */\n function authorizeHubByManager(address relayHub) external;\n\n /**\n * @notice Remove the `RelayHub` from a list of authorized by this Relay Manager.\n * @param relayManager The address of a Relay Manager.\n * @param relayHub The address of a `RelayHub` to be unauthorized.\n */\n function unauthorizeHubByOwner(address relayManager, address relayHub) external;\n\n /**\n * @notice Same as `unauthorizeHubByOwner` but can be called by the RelayManager itself.\n */\n function unauthorizeHubByManager(address relayHub) external;\n\n /**\n * Slash the stake of the relay relayManager. In order to prevent stake kidnapping, burns part of stake on the way.\n * @param relayManager The address of a Relay Manager to be penalized.\n * @param beneficiary The address that receives part of the penalty amount.\n * @param amount A total amount of penalty to be withdrawn from stake.\n */\n function penalizeRelayManager(address relayManager, address beneficiary, uint256 amount) external;\n\n /**\n * @notice Allows the contract owner to set the given `relayManager` as abandoned after a configurable delay.\n * Its entire stake and balance will be taken from a relay if it does not respond to being marked as abandoned.\n */\n function markRelayAbandoned(address relayManager) external;\n\n /**\n * @notice If more than `abandonmentDelay` has passed since the last Keepalive transaction, and relay manager\n * has been marked as abandoned, and after that more that `escheatmentDelay` have passed, entire stake and\n * balance will be taken from this relay.\n */\n function escheatAbandonedRelayStake(address relayManager) external;\n\n /**\n * @notice Sets a new `keepaliveTime` for the given `relayManager`, preventing it from being marked as abandoned.\n * Can be called by an authorized `RelayHub` or by the `relayOwner` address.\n */\n function updateRelayKeepaliveTime(address relayManager) external;\n\n /**\n * @notice Check if the Relay Manager can be considered abandoned or not.\n * Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.\n */\n function isRelayEscheatable(address relayManager) external view returns(bool);\n\n /**\n * @notice Get the stake details information for the given Relay Manager.\n * @param relayManager The address of a Relay Manager.\n * @return stakeInfo The `StakeInfo` structure.\n * @return isSenderAuthorizedHub `true` if the `msg.sender` for this call was a `RelayHub` that is authorized now.\n * `false` if the `msg.sender` for this call is not authorized.\n */\n function getStakeInfo(address relayManager) external view returns (StakeInfo memory stakeInfo, bool isSenderAuthorizedHub);\n\n /**\n * @return The maximum unstake delay this `StakeManger` allows. This is to prevent locking money forever by mistake.\n */\n function getMaxUnstakeDelay() external view returns (uint256);\n\n /**\n * @notice Change the address that will receive the 'burned' part of the penalized stake.\n * This is done to prevent malicious Relay Server from penalizing itself and breaking even.\n */\n function setBurnAddress(address _burnAddress) external;\n\n /**\n * @return The address that will receive the 'burned' part of the penalized stake.\n */\n function getBurnAddress() external view returns (address);\n\n /**\n * @notice Change the address that will receive the 'abandoned' stake.\n * This is done to prevent Relay Servers that lost their keys from losing access to funds.\n */\n function setDevAddress(address _burnAddress) external;\n\n /**\n * @return The structure that contains all configuration values for the 'abandoned' stake.\n */\n function getAbandonedRelayServerConfig() external view returns (AbandonedRelayServerConfig memory);\n\n /**\n * @return the block number in which the contract has been deployed.\n */\n function getCreationBlock() external view returns (uint256);\n\n /**\n * @return a SemVer-compliant version of the `StakeManager` contract.\n */\n function versionSM() external view returns (string memory);\n}" + }, + "contracts-link/Migrations.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier:MIT\n\ncontract Migrations {\n address public owner;\n // solhint-disable-next-line var-name-mixedcase\n uint256 public last_completed_migration;\n\n constructor() {\n owner = msg.sender;\n }\n\n modifier restricted() {\n if (msg.sender == owner) _;\n }\n\n function setCompleted(uint256 completed) public restricted {\n last_completed_migration = completed;\n }\n\n function upgrade(address newAddress) public restricted {\n Migrations upgraded = Migrations(newAddress);\n upgraded.setCompleted(last_completed_migration);\n }\n}" + }, + "contracts-link/paymasters/AcceptEverythingPaymaster.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma experimental ABIEncoderV2;\n\nimport \"@opengsn/contracts/src/BasePaymaster.sol\";\n\n// accept everything.\n// this paymaster accepts any request.\n//\n// NOTE: Do NOT use this contract on a mainnet: it accepts anything, so anyone can \"grief\" it and drain its account\n\ncontract AcceptEverythingPaymaster is BasePaymaster {\n\n function versionPaymaster() external view override virtual returns (string memory){\n return \"3.0.0-beta.3+opengsn.accepteverything.ipaymaster\";\n }\n\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n virtual\n returns (bytes memory context, bool revertOnRecipientRevert) {\n (relayRequest, signature, approvalData, maxPossibleGas);\n return (\"\", false);\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n virtual {\n (context, success, gasUseWithoutPost, relayData);\n }\n\n}\n" + }, + "contracts-link/paymasters/HashcashPaymaster.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma experimental ABIEncoderV2;\n\nimport \"./AcceptEverythingPaymaster.sol\";\n\n///A paymaster that requires some calculation from the client before accepting a request.\n///This comes to prevent attack by anonymous clients.\n/// Usage:\n/// - Create an instance of the HashcashPaymaster, and give it a proper difficulty level.\n/// - When creating a RelayProvider, make sure to use the createHashcashAsyncApproval() with\n/// the same difficulty level.\n///\n/// The \"difficulty\" level is the number of zero bits at the generated hash.\n/// a value of 15 requires roughly 32000 iterations and take ~0.5 second on a normal PC\ncontract HashcashPaymaster is AcceptEverythingPaymaster {\n\n function versionPaymaster() external view override virtual returns (string memory){\n return \"3.0.0-beta.3+opengsn.hashcash.ipaymaster\";\n }\n\n uint8 public difficulty;\n\n constructor(uint8 _difficulty) {\n difficulty = _difficulty;\n }\n\n function _verifyApprovalData(bytes calldata approvalData) internal virtual override view{\n // solhint-disable-next-line reason-string\n require(approvalData.length == 64, \"approvalData: invalid length for hash and nonce\");\n }\n\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n virtual\n returns (bytes memory, bool revertOnRecipientRevert) {\n (maxPossibleGas, signature);\n\n (bytes32 hash, uint256 hashNonce) = abi.decode(approvalData, (bytes32, uint256));\n bytes32 calcHash = keccak256(abi.encode(\n relayRequest.request.from,\n relayRequest.request.nonce,\n hashNonce));\n require(hash == calcHash, \"wrong hash\");\n require(uint256(hash) < (uint256(1) << (256 - difficulty)), \"difficulty not met\");\n return (\"\", false);\n }\n}\n" + }, + "contracts-link/paymasters/helpers/AllEvents.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.7;\n\n/**\n * In order to help the Truffle tests to decode events in the transactions' results,\n * the events must be declared in a top-level contract.\n * Implement this empty interface in order to add event signatures to any contract.\n *\n */\ninterface AllEvents {\n event Received(address indexed sender, uint256 eth);\n event Withdrawal(address indexed src, uint256 wad);\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n event TokensCharged(uint256 gasUseWithoutPost, uint256 gasJustPost, uint256 tokenActualCharge, uint256 ethActualCharge);\n event UniswapReverted(address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin);\n\n event Swap(\n address indexed sender,\n address indexed recipient,\n int256 amount0,\n int256 amount1,\n uint160 sqrtPriceX96,\n uint128 liquidity,\n int24 tick\n );\n}\n" + }, + "contracts-link/paymasters/helpers/ImportsArtifacts.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma experimental ABIEncoderV2;\n\n//\"import\" it into our project for Truffle to generate artifacts\nimport \"@opengsn/contracts/src/forwarder/IForwarder.sol\";\nimport \"@opengsn/contracts/src/forwarder/Forwarder.sol\";\nimport \"@opengsn/contracts/src/StakeManager.sol\";\nimport \"@opengsn/contracts/src/Penalizer.sol\";\nimport \"@opengsn/contracts/src/utils/RelayRegistrar.sol\";\nimport \"@opengsn/contracts/src/test/TestRecipient.sol\";\n\nimport \"@uniswap/v3-periphery/contracts/interfaces/IQuoter.sol\";\n" + }, + "contracts-link/paymasters/helpers/SampleRecipient.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma experimental ABIEncoderV2;\n\nimport \"@opengsn/contracts/src/ERC2771Recipient.sol\";\n\n// pass-through paymaster.\n// should override it and re-implement acceptRelayedCall. use \"super\" on success\ncontract SampleRecipient is ERC2771Recipient {\n\n event Sender( address _msgSenderFunc, address sender );\n\n function setForwarder(address forwarder) public {\n _setTrustedForwarder(forwarder);\n }\n\n function something() public {\n emit Sender( _msgSender(), msg.sender );\n }\n\n function nothing() public {\n emit Sender( _msgSender(), msg.sender );\n }\n}\n" + }, + "contracts-link/paymasters/helpers/TestCounter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ncontract TestCounter {\n uint256 public count;\n\n constructor () {\n count = 0;\n }\n\n function increment() public payable{\n count = count + 1;\n }\n\n function get() public view returns (uint256) {\n return count;\n }\n\n /* solhint-disable no-empty-blocks */\n receive() external payable {}\n fallback() external payable {}\n}\n" + }, + "contracts-link/paymasters/helpers/TestHub.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.0;\npragma experimental ABIEncoderV2;\n\nimport \"@opengsn/contracts/src/utils/GsnTypes.sol\";\nimport \"@opengsn/contracts/src/interfaces/IPaymaster.sol\";\n\nimport \"@opengsn/contracts/src/RelayHub.sol\";\n\nimport \"./AllEvents.sol\";\n\n/**\n * This mock relay hub contract is only used to test the paymaster's 'pre-' and 'postRelayedCall' in isolation.\n */\ncontract TestHub is RelayHub, AllEvents {\n\n constructor(\n IStakeManager _stakeManager,\n address _penalizer,\n address _batchGateway,\n address _relayRegistrar,\n RelayHubConfig memory _config) RelayHub(_stakeManager,\n _penalizer,\n _batchGateway,\n _relayRegistrar,\n _config)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function callPreRC(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n external\n returns (bytes memory context, bool revertOnRecipientRevert) {\n IPaymaster paymaster = IPaymaster(relayRequest.relayData.paymaster);\n IPaymaster.GasAndDataLimits memory limits = paymaster.getGasAndDataLimits();\n return paymaster.preRelayedCall{gas: limits.preRelayedCallGasLimit}(relayRequest, signature, approvalData, maxPossibleGas);\n }\n\n function callPostRC(\n IPaymaster paymaster,\n bytes calldata context,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n external {\n IPaymaster.GasAndDataLimits memory limits = paymaster.getGasAndDataLimits();\n paymaster.postRelayedCall{gas: limits.postRelayedCallGasLimit}(context, true, gasUseWithoutPost, relayData);\n }\n}\n" + }, + "contracts-link/paymasters/helpers/TestProxy.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"@opengsn/contracts/src/ERC2771Recipient.sol\";\n\ncontract TestProxy is ERC2771Recipient, Ownable {\n\n constructor(address forwarder) {\n _setTrustedForwarder(forwarder);\n }\n\n function isOwner() public view returns (bool) {\n return _msgSender() == owner();\n }\n\n event Test(address _msgSender, address msgSender);\n //not a proxy method; just for testing.\n function test() public {\n emit Test(_msgSender(), msg.sender);\n }\n\n function execute(address target, bytes calldata func) external onlyOwner {\n\n //solhint-disable-next-line\n (bool success, bytes memory ret) = target.call(func);\n require(success, string(ret));\n }\n\n function _msgSender() internal override(Context, ERC2771Recipient) view returns (address) {\n return ERC2771Recipient._msgSender();\n }\n\n function _msgData() internal override(Context, ERC2771Recipient) view returns (bytes memory) {\n return ERC2771Recipient._msgData();\n }\n}\n" + }, + "contracts-link/paymasters/helpers/TestUniswap.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@opengsn/contracts/src/test/TestToken.sol\";\n\nimport \"../interfaces/IUniswapV3.sol\";\n\n// naive, no-calculation swapper.\n//- the exchange rate is fixed at construction\n//- mints new tokens at will...\ncontract TestUniswap is IUniswapV3 {\n IERC20 public token;\n uint256 public rateMult;\n uint256 public rateDiv;\n\n constructor(uint256 _rateMult, uint256 _rateDiv) payable {\n token = new TestToken();\n rateMult = _rateMult;\n rateDiv = _rateDiv;\n require(msg.value > 0, \"must specify liquidity\");\n require(rateMult != 0 && rateDiv != 0, \"bad mult,div\");\n }\n\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n\n function tokenAddress() external override view returns (address out) {\n return address(token);\n }\n\n function tokenToEthSwapOutput(uint256 ethBought, uint256 maxTokens, uint256 deadline) public override returns (uint256 out) {\n (maxTokens, deadline);\n uint256 tokensToSell = getTokenToEthOutputPrice(ethBought);\n require(address(this).balance > ethBought, \"not enough liquidity\");\n\n token.transferFrom(msg.sender, address(this), tokensToSell);\n payable(msg.sender).transfer(ethBought);\n return tokensToSell;\n }\n\n function getTokenToEthInputPrice(uint256 tokensSold) external override view returns (uint256 out) {\n return tokensSold * rateDiv / rateMult;\n }\n\n function tokenToEthTransferOutput(uint256 ethBought, uint256 maxTokens, uint256 deadline, address payable recipient) external override returns (uint256 out) {\n (maxTokens, deadline, recipient);\n require(address(this).balance > ethBought, \"not enough liquidity\");\n\n uint256 tokensToSell = getTokenToEthOutputPrice(ethBought);\n\n token.transferFrom(msg.sender, address(this), tokensToSell);\n recipient.transfer(ethBought);\n return tokensToSell;\n }\n\n function getTokenToEthOutputPrice(uint256 ethBought) public override view returns (uint256 out) {\n return ethBought * rateMult / rateDiv;\n }\n\n function exactInputSingle(ExactInputSingleParams calldata) external override payable returns (uint256 amountOut) {\n revert(\"No swap for you\");\n }\n\n // solhint-disable-next-line no-empty-blocks\n function unwrapWETH9(uint256, address) external payable {}\n}\n" + }, + "contracts-link/paymasters/helpers/TokenGasCalculator.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.0;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"@opengsn/contracts/src/RelayHub.sol\";\nimport \"@opengsn/contracts/src/BasePaymaster.sol\";\nimport \"./AllEvents.sol\";\n\n/**\n * Calculate the postRelayedCall gas usage for a TokenPaymaster.\n *\n */\ncontract TokenGasCalculator is RelayHub, AllEvents {\n\n //(The Paymaster calls back calculateCharge, depositFor in the relayHub,\n //so the calculator has to implement them just like a real RelayHub\n // solhint-disable-next-line no-empty-blocks\n constructor(\n IStakeManager _stakeManager,\n address _penalizer,\n address _batchGateway,\n address _relayRegistrar,\n RelayHubConfig memory _config) RelayHub(_stakeManager,\n _penalizer,\n _batchGateway,\n _relayRegistrar,\n _config)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n /**\n * calculate actual cost of postRelayedCall.\n * usage:\n * - create this calculator.\n * - create an instance of your TokenPaymaster, with your token's Uniswap instance.\n * - move some tokens (1000 \"wei\") to the calculator (msg.sender is given approval to pull them back at the end)\n * - set the calculator as owner of this calculator.\n * - call this method.\n * - use the returned values to set your real TokenPaymaster.setPostGasUsage()\n * the above can be ran on a \"forked\" network, so that it will have the real token, uniswap instances,\n * but still leave no side-effect on the network.\n */\n function calculatePostGas(\n BasePaymaster paymaster,\n bytes memory ctx1,\n bytes memory paymasterData\n ) public returns (uint256 gasUsedByPost) {\n GsnTypes.RelayData memory relayData = GsnTypes.RelayData(1, 1, 0, address(0), address(0), address(0), paymasterData, 0);\n\n //with precharge\n uint256 gas0 = gasleft();\n paymaster.postRelayedCall(ctx1, true, 100, relayData);\n uint256 gas1 = gasleft();\n gasUsedByPost = gas0 - gas1;\n emit GasUsed(gasUsedByPost);\n }\n\n event GasUsed(uint256 gasUsedByPost);\n}\n\n" + }, + "contracts-link/paymasters/helpers/UniswapV3Helper.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.7;\npragma experimental ABIEncoderV2;\n\nimport \"@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol\";\nimport \"@uniswap/v3-periphery/contracts/interfaces/IPeripheryPayments.sol\";\n\nlibrary UniswapV3Helper {\n event UniswapReverted(address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin);\n // turn ERC-20 tokens into wrapped ETH at market price\n function swapToWeth(\n address token,\n address weth,\n uint256 amountOut,\n uint24 fee,\n ISwapRouter uniswap\n ) internal returns (uint256 amountIn) {\n ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter.ExactOutputSingleParams(\n token, //tokenIn\n weth, //tokenOut\n fee,\n address(uniswap), //recipient - keep WETH at SwapRouter for withdrawal\n // solhint-disable-next-line not-rely-on-time\n block.timestamp, //deadline\n amountOut,\n type(uint256).max,\n 0\n );\n amountIn = uniswap.exactOutputSingle(params);\n }\n\n function unwrapWeth(ISwapRouter uniswap, uint256 amount) internal {\n IPeripheryPayments(address(uniswap)).unwrapWETH9(amount, address(this));\n }\n\n // swap ERC-20 tokens at market price\n function swapToToken(\n address tokenIn,\n address tokenOut,\n uint256 amountIn,\n uint256 amountOutMin,\n uint24 fee,\n ISwapRouter uniswap\n ) internal returns (uint256 amountOut) {\n ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams(\n tokenIn, //tokenIn\n tokenOut, //tokenOut\n fee,\n address(uniswap),\n // solhint-disable-next-line not-rely-on-time\n block.timestamp, //deadline\n amountIn,\n amountOutMin,\n 0\n );\n try uniswap.exactInputSingle(params) returns (uint256 _amountOut) {\n amountOut = _amountOut;\n } catch {\n emit UniswapReverted(tokenIn, tokenOut, amountIn, amountOutMin);\n amountOut = 0;\n }\n }\n}\n" + }, + "contracts-link/paymasters/interfaces/IChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.7;\n\ninterface IChainlinkOracle {\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function latestAnswer() external view returns (int256);\n}\n" + }, + "contracts-link/paymasters/interfaces/IERC725.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IERC725 {\n event DataChanged(bytes32 indexed key, bytes indexed value);\n event OwnerChanged(address indexed ownerAddress);\n event ContractCreated(address indexed contractAddress);\n\n function owner() external view returns (address);\n\n function changeOwner(address _owner) external;\n\n function getData(bytes32 _key) external view returns (bytes memory _value);\n\n function setData(bytes32 _key, bytes calldata _value) external;\n\n function execute(uint256 _operationType, address _to, uint256 _value, bytes calldata _data) external payable;\n}\n" + }, + "contracts-link/paymasters/interfaces/IUniswapV3.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.7;\n\n//minimal uniswap we need:\ninterface IUniswapV3 {\n function tokenAddress() external view returns (address);\n\n function tokenToEthSwapOutput(uint256 ethBought, uint256 maxTokens, uint256 deadline) external returns (uint256 out);\n\n function tokenToEthTransferOutput(uint256 ethBought, uint256 maxTokens, uint256 deadline, address payable recipient) external returns (uint256 out);\n\n function getTokenToEthOutputPrice(uint256 ethBought) external view returns (uint256 out);\n\n function getTokenToEthInputPrice(uint256 tokensSold) external view returns (uint256 out);\n\n struct ExactInputSingleParams {\n address tokenIn;\n address tokenOut;\n uint24 fee;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n uint160 sqrtPriceLimitX96;\n }\n\n function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);\n\n}\n" + }, + "contracts-link/paymasters/interfaces/PermitInterfaceDAI.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\ninterface PermitInterfaceDAI is IERC20Metadata {\n function nonces(address holder) external view returns (uint256 nonce);\n\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n}\n" + }, + "contracts-link/paymasters/interfaces/PermitInterfaceEIP2612.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\ninterface PermitInterfaceEIP2612 is IERC20Metadata {\n function nonces(address holder) external view returns (uint256 nonce);\n\n // --- Approve by signature ---\n function permit(address owner, address spender, uint256 value, uint256 deadline,\n uint8 v, bytes32 r, bytes32 s) external;\n}\n" + }, + "contracts-link/paymasters/PermitERC20UniswapV3Paymaster.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.7;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol\";\n\nimport \"@opengsn/contracts/src/forwarder/IForwarder.sol\";\nimport \"@opengsn/contracts/src/ERC2771Recipient.sol\";\nimport \"@opengsn/contracts/src/BasePaymaster.sol\";\nimport \"@opengsn/contracts/src/utils/GsnUtils.sol\";\n\nimport \"./interfaces/IChainlinkOracle.sol\";\n\nimport \"./helpers/UniswapV3Helper.sol\";\n\n/**\n * A paymaster allowing addresses holding ERC20 tokens with 'permit' functionality\n * to pay for a GSN transaction.\n */\ncontract PermitERC20UniswapV3Paymaster is BasePaymaster, ERC2771Recipient {\n\n using SafeERC20 for IERC20;\n\n event Received(address indexed sender, uint256 eth);\n event TokensCharged(uint256 gasUseWithoutPost, uint256 gasJustPost, uint256 tokenActualCharge, uint256 ethActualCharge);\n\n struct TokenSwapData {\n IChainlinkOracle priceFeed;\n // in case the chainlink oracle exposes price quote as \"ETH / Token\" we need to reverse the calculation\n bool reverseQuote;\n uint24 uniswapPoolFee;\n // between 0 to 1000, with 2 decimals, that is, 10 = 1%\n uint8 slippage;\n bytes4 permitMethodSelector;\n uint256 priceDivisor;\n uint256 validFromBlockNumber;\n }\n\n mapping(IERC20 => TokenSwapData) public tokensSwapData;\n ISwapRouter public uniswap;\n IERC20[] public tokens;\n IERC20 public weth;\n uint256 public tokensBlockNumber;\n uint256 public gasUsedByPost;\n uint256 public minHubBalance;\n uint256 public targetHubBalance;\n uint256 public minWithdrawalAmount;\n uint256 public minSwapAmount;\n uint256 public paymasterFee;\n\n struct UniswapConfig {\n ISwapRouter uniswap;\n IERC20 weth;\n // Minimum eth amount to get from a swap\n uint256 minSwapAmount;\n IERC20[] tokens;\n IChainlinkOracle[] priceFeeds;\n uint24[] uniswapPoolFees;\n string[] permitMethodSignatures;\n uint8[] slippages;\n bool[] reverseQuotes;\n }\n\n struct GasAndEthConfig {\n /**\n * set gas used by postRelayedCall, for proper gas calculation.\n * You can use TokenGasCalculator to calculate these values (they depend on actual code of postRelayedCall,\n * but also the gas usage of the token and of Uniswap)\n */\n uint256 gasUsedByPost;\n // Upon reaching minHubBalance, the paymaster will deposit eth to RelayHub to reach targetHubBalance\n uint256 minHubBalance;\n uint256 targetHubBalance;\n // Minimum eth amount, above targetHubBalance, to send to the owner\n uint256 minWithdrawalAmount;\n uint256 paymasterFee;\n }\n\n constructor(\n UniswapConfig memory uniswapConfig,\n GasAndEthConfig memory gasAndEthConfig,\n address _trustedForwarder,\n IRelayHub _relayHub\n ) {\n setUniswapConfig(uniswapConfig);\n setGasAndEthConfig(gasAndEthConfig);\n\n setRelayHub(_relayHub);\n setTrustedForwarder(_trustedForwarder);\n }\n\n function setUniswapConfig(UniswapConfig memory config) public onlyOwner {\n weth = config.weth;\n uniswap = config.uniswap;\n minSwapAmount = config.minSwapAmount;\n setTokens(config.tokens, config.priceFeeds, config.permitMethodSignatures, config.uniswapPoolFees, config.reverseQuotes, config.slippages);\n }\n\n function setGasAndEthConfig(GasAndEthConfig memory config) public onlyOwner {\n minWithdrawalAmount = config.minWithdrawalAmount;\n gasUsedByPost = config.gasUsedByPost;\n targetHubBalance = config.targetHubBalance;\n minHubBalance = config.minHubBalance;\n paymasterFee = config.paymasterFee;\n }\n\n function setTokens(\n IERC20[] memory _tokens,\n IChainlinkOracle[] memory _priceFeeds,\n string[] memory _permitMethodSignatures,\n uint24[] memory _poolFees,\n bool[] memory _reverseQuote,\n uint8[] memory _slippages) private {\n tokens = _tokens;\n uint256 blockNumber = block.number;\n tokensBlockNumber = blockNumber;\n // allow uniswap to transfer from paymaster balance\n for (uint256 i = 0; i < tokens.length; i++) {\n TokenSwapData memory data;\n IERC20 token = tokens[i];\n token.approve(address(uniswap), type(uint256).max);\n data.priceDivisor = 10 ** uint256(_priceFeeds[i].decimals() + IERC20Metadata(address(token)).decimals());\n data.priceFeed = _priceFeeds[i];\n data.reverseQuote = _reverseQuote[i];\n data.permitMethodSelector = bytes4(keccak256(bytes(_permitMethodSignatures[i])));\n data.uniswapPoolFee = _poolFees[i];\n require(_slippages[i] <= 1000, \"slippage above 100%\");\n data.slippage = _slippages[i];\n data.validFromBlockNumber = blockNumber;\n tokensSwapData[token] = data;\n }\n }\n\n function getTokens() public view returns (IERC20[] memory){\n return tokens;\n }\n\n function getTokenSwapData(IERC20 token) public view returns (TokenSwapData memory) {\n return tokensSwapData[token];\n }\n\n function refillHubDeposit(uint256 amount) public payable onlyOwner {\n _refillHubDeposit(amount);\n }\n\n function withdrawTokens(IERC20[] calldata _tokens, address target, uint256[] calldata amounts) public onlyOwner {\n for (uint256 i = 0; i < _tokens.length; i++) {\n _tokens[i].safeTransfer(target, amounts[i]);\n }\n }\n\n function _calculateCharge(\n GsnTypes.RelayData calldata relayData,\n uint256 gasUsed,\n uint256 priceQuote,\n bool reverseQuote\n ) internal\n view\n returns (uint256 tokenCharge, uint256 ethCharge) {\n ethCharge = relayHub.calculateCharge(gasUsed, relayData);\n tokenCharge = addPaymasterFee(weiToToken(ethCharge, priceQuote, reverseQuote));\n }\n\n function toActualQuote(uint256 quote, uint256 divisor) public pure returns (uint256) {\n // converting oracle token-to-eth answer, to token to wei (*1e18), packing divisor (/divisor) to it\n // multiplying by 1e36 to avoid loss of precision by dividing by divisor\n return 1e36 * 1e18 * quote / divisor;\n }\n\n function tokenToWei(uint256 amount, uint256 quote, bool reverse) public pure returns (uint256) {\n if (reverse){\n return weiToToken(amount, quote, false);\n }\n return amount * quote / 1e36;\n }\n\n function weiToToken(uint256 amount, uint256 quote, bool reverse) public pure returns (uint256) {\n if (reverse){\n return tokenToWei(amount, quote, false);\n }\n return amount * 1e36 / quote;\n }\n\n // solhint-disable-next-line no-empty-blocks\n function _verifyPaymasterData(GsnTypes.RelayRequest calldata relayRequest) internal virtual override view {}\n\n function isTokenSupported(IERC20 token) public view returns (bool) {\n return tokensSwapData[token].validFromBlockNumber == tokensBlockNumber;\n }\n\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n returns (bytes memory, bool) {\n (signature, approvalData);\n bytes calldata paymasterData = relayRequest.relayData.paymasterData;\n // paymasterData must contain the token address, and optionally a a valid \"permit\" call on the token.\n require(paymasterData.length >= 20, \"must contain token address\");\n IERC20 token = _getTokenFromPaymasterData(paymasterData);\n require(isTokenSupported(token),\"unsupported token\");\n TokenSwapData memory tokenSwapData = tokensSwapData[token];\n if (paymasterData.length != 20) {\n require(paymasterData.length >= 24, \"must contain \\\"permit\\\" and token\");\n require(\n tokenSwapData.permitMethodSelector == GsnUtils.getMethodSig(paymasterData[20:]),\n \"wrong \\\"permit\\\" method sig\");\n // execute permit method for this token\n {\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory ret) = address(token).call(paymasterData[20:]);\n require(success, string(abi.encodePacked(\"permit call reverted:\", string(ret))));\n }\n }\n\n uint256 priceQuote = toActualQuote(uint256(tokenSwapData.priceFeed.latestAnswer()),tokenSwapData.priceDivisor);\n\n (uint256 tokenPreCharge,) = _calculateCharge(relayRequest.relayData, maxPossibleGas, priceQuote, tokenSwapData.reverseQuote);\n address payer = relayRequest.request.from;\n token.safeTransferFrom(payer, address(this), tokenPreCharge);\n return (abi.encode(token, payer, priceQuote, tokenPreCharge, tokenSwapData.reverseQuote), false);\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n {\n (IERC20 token, address payer, uint256 priceQuote, uint256 tokenPreCharge, bool reverseQuote) = abi.decode(context, (IERC20, address, uint256, uint256, bool));\n (uint256 tokenActualCharge, uint256 ethActualCharge) = _calculateCharge(relayData, gasUseWithoutPost + gasUsedByPost, priceQuote, reverseQuote);\n require(tokenActualCharge <= tokenPreCharge, \"actual charge higher\");\n token.safeTransfer(payer, tokenPreCharge - tokenActualCharge);\n\n emit TokensCharged(gasUseWithoutPost, gasUsedByPost, tokenActualCharge, ethActualCharge);\n _refillHubDepositIfNeeded(ethActualCharge);\n _withdrawToOwnerIfNeeded();\n }\n\n function _refillHubDepositIfNeeded(uint256 ethActualCharge) private {\n uint256 hubBalance = relayHub.balanceOf(address(this));\n if (hubBalance >= minHubBalance + ethActualCharge) {\n return;\n }\n uint256 depositAmount = targetHubBalance - hubBalance + ethActualCharge;\n _refillHubDeposit(depositAmount);\n }\n\n function _refillHubDeposit(uint256 depositAmount) private {\n uint256 balance = address(this).balance;\n uint256 amountSwapped = 0;\n if (balance < depositAmount) {\n for (uint256 i = 0; i < tokens.length && balance + amountSwapped < depositAmount; i++) {\n amountSwapped += _maybeSwapTokenToWeth(tokens[i]);\n }\n if (amountSwapped > 0) {\n UniswapV3Helper.unwrapWeth(uniswap, amountSwapped);\n }\n }\n if (balance + amountSwapped > 0) {\n relayHub.depositFor{value : balance + amountSwapped}(address(this));\n }\n }\n\n function _maybeSwapTokenToWeth(IERC20 tokenIn) private returns (uint256) {\n uint256 tokenBalance = tokenIn.balanceOf(address(this));\n if (tokenBalance > 0) {\n TokenSwapData memory tokenSwapData = tokensSwapData[tokenIn];\n uint256 quote = toActualQuote(uint256(tokenSwapData.priceFeed.latestAnswer()), tokenSwapData.priceDivisor);\n uint256 amountOutMin = addSlippage(tokenToWei(tokenBalance, quote, tokenSwapData.reverseQuote), tokenSwapData.slippage);\n if (amountOutMin < minSwapAmount) {\n return 0;\n }\n return UniswapV3Helper.swapToToken(\n address(tokenIn),\n address(weth),\n tokenBalance,\n amountOutMin,\n tokenSwapData.uniswapPoolFee,\n uniswap\n );\n }\n return 0;\n }\n\n function _withdrawToOwnerIfNeeded() private {\n uint256 hubBalance = relayHub.balanceOf(address(this));\n if (hubBalance >= minWithdrawalAmount + targetHubBalance) {\n relayHub.withdraw(payable(owner()), hubBalance - targetHubBalance);\n }\n }\n\n function _getTokenFromPaymasterData(bytes calldata paymasterData) internal pure returns (IERC20) {\n return IERC20(address(bytes20(paymasterData[:20])));\n }\n\n function addPaymasterFee(uint256 charge) public view returns (uint256) {\n return charge * (100 + paymasterFee) / 100;\n }\n\n function addSlippage(uint256 amount, uint8 slippage) public pure returns (uint256) {\n return amount * (1000 - slippage) / 1000;\n }\n\n // as this Paymaster already has a permission from a user to operate the tokens on behalf of the gasless account,\n // it makes this same Paymaster a great recipient of a transaction if its only action is a pure token transfer\n function transferToken(IERC20 token, address target, uint256 value) external {\n require(msg.sender == getTrustedForwarder(), \"must be a meta-tx\");\n token.safeTransferFrom(_msgSender(), target, value);\n }\n\n receive() external override payable {\n emit Received(msg.sender, msg.value);\n }\n\n function getGasAndDataLimits() public override pure returns (IPaymaster.GasAndDataLimits memory limits) {\n return IPaymaster.GasAndDataLimits(\n 2e5,\n 2e5,\n 4e5,\n CALLDATA_SIZE_LIMIT\n );\n }\n\n function versionPaymaster() external override virtual view returns (string memory){\n return \"3.0.0-beta.3+opengsn.permit-erc20-uniswap-v3.ipaymaster\";\n }\n\n function getTrustedForwarder() override(BasePaymaster, ERC2771Recipient) public view returns (address forwarder){\n forwarder = ERC2771Recipient.getTrustedForwarder();\n }\n\n function setTrustedForwarder(address _forwarder) public override onlyOwner {\n _setTrustedForwarder(_forwarder);\n }\n\n function _msgSender() internal view override(Context, ERC2771Recipient) returns (address sender) {\n sender = ERC2771Recipient._msgSender();\n }\n\n function _msgData() internal view override(Context, ERC2771Recipient) returns (bytes memory) {\n return ERC2771Recipient._msgData();\n }\n}\n" + }, + "contracts-link/paymasters/SingleRecipientPaymaster.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma experimental ABIEncoderV2;\n\nimport \"@opengsn/contracts/src/BasePaymaster.sol\";\n\n/**\n * a paymaster for a single recipient contract.\n * - reject requests if destination is not the target contract.\n * - reject any request if the target contract reverts.\n */\ncontract SingleRecipientPaymaster is BasePaymaster {\n\n address public target;\n\n event TargetChanged(address oldTarget, address newTarget);\n\n function versionPaymaster() external view override virtual returns (string memory){\n return \"3.0.0-beta.3+opengsn.recipient.ipaymaster\";\n }\n\n function setTarget(address _target) external onlyOwner {\n emit TargetChanged(target, _target);\n target=_target;\n }\n\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n virtual\n returns (bytes memory context, bool revertOnRecipientRevert) {\n (relayRequest, signature, approvalData, maxPossibleGas);\n require(relayRequest.request.to==target, \"wrong target\");\n\t//returning \"true\" means this paymaster accepts all requests that\n\t// are not rejected by the recipient contract.\n return (\"\", true);\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n virtual {\n (context, success, gasUseWithoutPost, relayData);\n }\n}\n" + }, + "contracts-link/paymasters/SingletonWhitelistPaymaster.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma experimental ABIEncoderV2;\n\nimport \"@opengsn/contracts/src/BasePaymaster.sol\";\n\n/**\n * This Paymaster allows the dapp owners to maintain a simple set of rules on-chain for their GSN integrations.\n * Supports enabling specified target contracts (Recipients), senders and methods (per target) to be subsidized.\n * Unlike 'VerifyingPaymaster' doesn't require any server-side code but also does not provide any additional protection.\n */\ncontract SingletonWhitelistPaymaster is BasePaymaster {\n\n struct DappInformation {\n uint256 balance;\n bool useSenderWhitelist;\n bool useTargetWhitelist;\n bool useMethodWhitelist;\n mapping(address => bool) senderWhitelist;\n mapping(address => bool) targetWhitelist;\n mapping(address => mapping(bytes4 => bool)) methodWhitelist;\n }\n\n event WhitelistedTargets(address indexed dappOwner, uint256 count);\n event WhitelistedSenders(address indexed dappOwner, uint256 count);\n event WhitelistedMethodsForTarget(address indexed dappOwner, address indexed target, uint256 count);\n\n event Received(address dappOwner, uint256 amount, uint256 balance);\n event Withdrawn(address dappOwner, uint256 amount, uint256 balance);\n event AdminOverrideWithdrawn(address destination, uint256 amount);\n event SharedConfigChanged(uint256 gasUsedByPost, uint256 paymasterFee);\n event DappConfigChanged(address indexed dappOwner, bool useSenderWhitelist, bool useTargetWhitelist, bool useMethodWhitelist);\n event PostRelayedCall(address indexed dappOwner, uint256 gasUseWithoutPost, uint256 totalCharge, uint256 paymasterCharge);\n\n mapping(address => DappInformation) public registeredDapps;\n uint256 public gasUsedByPost;\n uint256 public paymasterFee;\n\n // Custom reentrancy guard as we want to cover 3 methods: 'preRelayedCall', 'withdrawBalance' and 'postRelayedCall'\n uint256 private constant NOT_ENTERED = 1;\n uint256 private constant ENTERED = 2;\n uint256 private status = NOT_ENTERED;\n\n function versionPaymaster() external view override virtual returns (string memory){\n return \"3.0.0-beta.3+opengsn.singleton-whitelist.ipaymaster\";\n }\n\n function whitelistSenders(address[] memory senders, bool isAllowed) external {\n address dappOwner = msg.sender;\n for (uint256 i = 0; i < senders.length; i++) {\n registeredDapps[dappOwner].senderWhitelist[senders[i]] = isAllowed;\n }\n emit WhitelistedSenders(dappOwner, senders.length);\n }\n\n function whitelistTargets(address[] memory targets, bool isAllowed) external {\n address dappOwner = msg.sender;\n for (uint256 i = 0; i < targets.length; i++) {\n registeredDapps[dappOwner].targetWhitelist[targets[i]] = isAllowed;\n }\n emit WhitelistedTargets(dappOwner, targets.length);\n }\n\n function whitelistMethodsForTarget(address target, bytes4[] memory methods, bool isAllowed) external {\n address dappOwner = msg.sender;\n for (uint256 i = 0; i < methods.length; i++) {\n registeredDapps[dappOwner].methodWhitelist[target][methods[i]] = isAllowed;\n }\n emit WhitelistedMethodsForTarget(dappOwner, target, methods.length);\n }\n\n function setSharedConfiguration(uint256 _gasUsedByPost, uint256 _paymasterFee) external onlyOwner {\n gasUsedByPost = _gasUsedByPost;\n paymasterFee = _paymasterFee;\n emit SharedConfigChanged(gasUsedByPost, paymasterFee);\n }\n\n function setDappConfiguration(\n bool _useSenderWhitelist,\n bool _useTargetWhitelist,\n bool _useMethodWhitelist\n ) external {\n DappInformation storage dappInfo = registeredDapps[msg.sender];\n dappInfo.useSenderWhitelist = _useSenderWhitelist;\n dappInfo.useTargetWhitelist = _useTargetWhitelist;\n dappInfo.useMethodWhitelist = _useMethodWhitelist;\n emit DappConfigChanged(msg.sender, _useSenderWhitelist, _useTargetWhitelist, _useMethodWhitelist);\n }\n\n function _verifyPaymasterData(GsnTypes.RelayRequest calldata relayRequest) internal virtual override view {\n require(relayRequest.relayData.paymasterData.length == 32, \"paymasterData: invalid length\");\n }\n\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n virtual\n returns (bytes memory context, bool revertOnRecipientRevert) {\n (signature, approvalData, maxPossibleGas);\n status = ENTERED;\n address dappOwner = abi.decode(relayRequest.relayData.paymasterData, (address));\n DappInformation storage targetConfiguration = registeredDapps[dappOwner];\n if (!(targetConfiguration.useSenderWhitelist\n || targetConfiguration.useTargetWhitelist\n || targetConfiguration.useMethodWhitelist)\n ) {\n revert(\"turning off checks is forbidden\");\n }\n\n uint256 maxPossibleCharge = relayHub.calculateCharge(maxPossibleGas, relayRequest.relayData);\n uint256 totalMaxPossibleCharge = addPaymasterFee(maxPossibleCharge);\n require(registeredDapps[dappOwner].balance >= totalMaxPossibleCharge, \"insufficient balance for charge\");\n\n if (targetConfiguration.useSenderWhitelist) {\n address sender = relayRequest.request.from;\n require(targetConfiguration.senderWhitelist[sender], \"sender not whitelisted\");\n }\n if (targetConfiguration.useTargetWhitelist) {\n address target = relayRequest.request.to;\n require(targetConfiguration.targetWhitelist[target], \"target not whitelisted\");\n }\n if (targetConfiguration.useMethodWhitelist) {\n address target = relayRequest.request.to;\n bytes4 method = GsnUtils.getMethodSig(relayRequest.request.data);\n require(targetConfiguration.methodWhitelist[target][method], \"method not whitelisted\");\n }\n\n return (relayRequest.relayData.paymasterData, true);\n }\n\n function isSenderWhitelistedForDappOwner(\n address dappOwner,\n address sender\n )\n external\n view\n returns (bool)\n {\n return registeredDapps[dappOwner].senderWhitelist[sender];\n }\n\n function isTargetWhitelistedForDappOwner(\n address dappOwner,\n address target\n )\n external\n view\n returns (bool)\n {\n return registeredDapps[dappOwner].targetWhitelist[target];\n }\n\n function isMethodWhitelistedForTargetAndDappOwner(\n address dappOwner,\n address target,\n bytes4 method\n )\n external\n view\n returns (bool)\n {\n return registeredDapps[dappOwner].methodWhitelist[target][method];\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n virtual {\n (success);\n status = NOT_ENTERED;\n address dappOwner = abi.decode(context, (address));\n uint256 gasUsed = gasUseWithoutPost + gasUsedByPost;\n uint256 actualCharge = relayHub.calculateCharge(gasUsed, relayData);\n uint256 totalCharge = addPaymasterFee(actualCharge);\n uint256 paymasterCharge = totalCharge - actualCharge;\n require(registeredDapps[dappOwner].balance >= totalCharge, \"insufficient balance for charge\");\n registeredDapps[dappOwner].balance -= totalCharge;\n registeredDapps[owner()].balance += paymasterCharge;\n emit PostRelayedCall(dappOwner, gasUseWithoutPost, totalCharge, paymasterCharge);\n }\n\n // TODO: this is now a shared code. consider extracting to base / library.\n function addPaymasterFee(uint256 charge) public view returns (uint256) {\n return charge * (100 + paymasterFee) / 100;\n }\n\n receive() external override payable {\n require(address(relayHub) != address(0), \"relay hub address not set\");\n relayHub.depositFor{value : msg.value}(address(this));\n registeredDapps[msg.sender].balance += msg.value;\n emit Received(msg.sender, msg.value, registeredDapps[msg.sender].balance);\n }\n\n function withdrawBalance(uint256 amount) external {\n require(status != ENTERED, \"withdrawBalance reentrant call\");\n require(address(relayHub) != address(0), \"relay hub address not set\");\n require(registeredDapps[msg.sender].balance >= amount, \"dapp owner balance insufficient\");\n registeredDapps[msg.sender].balance -= amount;\n relayHub.withdraw(payable(msg.sender), amount);\n emit Withdrawn(msg.sender, amount, registeredDapps[msg.sender].balance);\n }\n\n /// @notice Allows the 'owner' of this Paymaster to extract funds from the RelayHub overriding the depositors.\n /// @notice This is necessary in case there is a security vulnerability discovered.\n /// @notice If 'totalCharge' calculation diverges from the RelayHub it would lead to funds being stuck as well.\n function adminOverrideWithdraw(address destination, uint256 amount) external onlyOwner {\n relayHub.withdraw(payable(destination), amount);\n emit AdminOverrideWithdrawn(destination, amount);\n }\n}\n" + }, + "contracts-link/paymasters/TokenPaymaster.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.8.0;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"@opengsn/contracts/src/forwarder/IForwarder.sol\";\nimport \"@opengsn/contracts/src/BasePaymaster.sol\";\n\nimport \"./interfaces/IUniswapV3.sol\";\n\n/**\n * A Token-based paymaster.\n * - each request is paid for by the caller.\n * - acceptRelayedCall - verify the caller can pay for the request in tokens.\n * - preRelayedCall - pre-pay the maximum possible price for the tx\n * - postRelayedCall - refund the caller for the unused gas\n */\ncontract TokenPaymaster is BasePaymaster {\n\n function versionPaymaster() external override virtual view returns (string memory){\n return \"3.0.0-beta.3+opengsn.token.ipaymaster\";\n }\n\n\n IUniswapV3[] public uniswaps;\n IERC20[] public tokens;\n\n mapping (IUniswapV3=>bool ) private supportedUniswaps;\n\n uint256 public gasUsedByPost;\n\n constructor(IUniswapV3[] memory _uniswaps) {\n uniswaps = _uniswaps;\n\n for (uint256 i = 0; i < _uniswaps.length; i++){\n supportedUniswaps[_uniswaps[i]] = true;\n tokens.push(IERC20(_uniswaps[i].tokenAddress()));\n tokens[i].approve(address(_uniswaps[i]), type(uint256).max);\n }\n }\n\n /**\n * set gas used by postRelayedCall, for proper gas calculation.\n * You can use TokenGasCalculator to calculate these values (they depend on actual code of postRelayedCall,\n * but also the gas usage of the token and of Uniswap)\n */\n function setPostGasUsage(uint256 _gasUsedByPost) external onlyOwner {\n gasUsedByPost = _gasUsedByPost;\n }\n\n // return the payer of this request.\n // for account-based target, this is the target account.\n function getPayer(GsnTypes.RelayRequest calldata relayRequest) public virtual view returns (address) {\n (this);\n return relayRequest.request.to;\n }\n\n event Received(uint256 eth);\n receive() external override payable {\n emit Received(msg.value);\n }\n\n function _getToken(bytes memory paymasterData) internal view returns (IERC20 token, IUniswapV3 uniswap) {\n uniswap = abi.decode(paymasterData, (IUniswapV3));\n require(supportedUniswaps[uniswap], \"unsupported token uniswap\");\n token = IERC20(uniswap.tokenAddress());\n }\n\n function _calculatePreCharge(\n IERC20 token,\n IUniswapV3 uniswap,\n GsnTypes.RelayRequest calldata relayRequest,\n uint256 maxPossibleGas)\n internal\n view\n returns (address payer, uint256 tokenPreCharge) {\n (token);\n payer = this.getPayer(relayRequest);\n uint256 ethMaxCharge = relayHub.calculateCharge(maxPossibleGas, relayRequest.relayData);\n ethMaxCharge += relayRequest.request.value;\n tokenPreCharge = uniswap.getTokenToEthOutputPrice(ethMaxCharge);\n }\n\n function _verifyPaymasterData(GsnTypes.RelayRequest calldata relayRequest) internal virtual override view {\n // solhint-disable-next-line reason-string\n require(relayRequest.relayData.paymasterData.length == 32, \"paymasterData: invalid length for Uniswap v3 exchange address\");\n }\n\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n virtual\n returns (bytes memory context, bool revertOnRecipientRevert) {\n (signature, approvalData);\n\n (IERC20 token, IUniswapV3 uniswap) = _getToken(relayRequest.relayData.paymasterData);\n (address payer, uint256 tokenPrecharge) = _calculatePreCharge(token, uniswap, relayRequest, maxPossibleGas);\n token.transferFrom(payer, address(this), tokenPrecharge);\n return (abi.encode(payer, tokenPrecharge, token, uniswap), false);\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n virtual\n {\n (address payer, uint256 tokenPrecharge, IERC20 token, IUniswapV3 uniswap) = abi.decode(context, (address, uint256, IERC20, IUniswapV3));\n _postRelayedCallInternal(payer, tokenPrecharge, 0, gasUseWithoutPost, relayData, token, uniswap);\n }\n\n function _postRelayedCallInternal(\n address payer,\n uint256 tokenPrecharge,\n uint256 valueRequested,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData,\n IERC20 token,\n IUniswapV3 uniswap\n ) internal {\n uint256 ethActualCharge = relayHub.calculateCharge(gasUseWithoutPost + gasUsedByPost, relayData);\n uint256 tokenActualCharge = uniswap.getTokenToEthOutputPrice(valueRequested + ethActualCharge);\n uint256 tokenRefund = tokenPrecharge - tokenActualCharge;\n _refundPayer(payer, token, tokenRefund);\n _depositProceedsToHub(ethActualCharge, uniswap);\n emit TokensCharged(gasUseWithoutPost, gasUsedByPost, ethActualCharge, tokenActualCharge);\n }\n\n function _refundPayer(\n address payer,\n IERC20 token,\n uint256 tokenRefund\n ) private {\n require(token.transfer(payer, tokenRefund), \"failed refund\");\n }\n\n function _depositProceedsToHub(uint256 ethActualCharge, IUniswapV3 uniswap) private {\n //solhint-disable-next-line\n uniswap.tokenToEthSwapOutput(ethActualCharge, type(uint256).max, block.timestamp+60*15);\n relayHub.depositFor{value:ethActualCharge}(address(this));\n }\n\n event TokensCharged(uint256 gasUseWithoutPost, uint256 gasJustPost, uint256 ethActualCharge, uint256 tokenActualCharge);\n}\n" + }, + "contracts-link/paymasters/VerifyingPaymaster.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma experimental ABIEncoderV2;\n\nimport \"@opengsn/contracts/src/BasePaymaster.sol\";\nimport \"@opengsn/contracts/src/forwarder/IForwarder.sol\";\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\n/**\n * a sample paymaster that requires an external signature on the request.\n * - the client creates a request.\n * - the client uses a RelayProvider with a callback function asyncApprovalData\n * - the callback sends the request over to a dapp-specific web service, to verify the request.\n * - the service verifies the request, signs it and return the signature.\n * - the client now sends this signed approval as the \"approvalData\" field of the GSN request.\n * - the paymaster verifies the signature.\n * This way, any external logic can be used to validate the request.\n * e.g.:\n * - OAuth, or any other login mechanism.\n * - Captcha approval\n * - off-chain payment system (note that its a payment for gas, so probably it doesn't require any KYC)\n * - etc.\n */\ncontract VerifyingPaymaster is Ownable, BasePaymaster {\n address private constant DRY_RUN_ADDRESS = 0x0000000000000000000000000000000000000000;\n\n address public signer;\n\n function _verifyApprovalData(bytes calldata approvalData) internal virtual override view {\n // solhint-disable-next-line avoid-tx-origin\n if (tx.origin != DRY_RUN_ADDRESS) {\n // solhint-disable-next-line reason-string\n require(approvalData.length == 65, \"approvalData: invalid length for signature\");\n }\n }\n\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n virtual\n returns (bytes memory context, bool revertOnRecipientRevert) {\n (signature, maxPossibleGas);\n\n bytes32 requestHash = getRequestHash(relayRequest);\n // solhint-disable-next-line avoid-tx-origin\n if (tx.origin != DRY_RUN_ADDRESS) {\n require(signer == ECDSA.recover(requestHash, approvalData), \"approvalData: wrong signature\");\n }\n return (\"\", false);\n }\n\n function getRequestHash(GsnTypes.RelayRequest calldata relayRequest) public pure returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n packForwardRequest(relayRequest.request),\n packRelayData(relayRequest.relayData)\n )\n );\n }\n\n function packForwardRequest(IForwarder.ForwardRequest calldata req) public pure returns (bytes memory) {\n return abi.encode(req.from, req.to, req.value, req.gas, req.nonce, req.data);\n }\n\n function packRelayData(GsnTypes.RelayData calldata d) public pure returns (bytes memory) {\n return abi.encode(d.maxFeePerGas, d.maxPriorityFeePerGas, d.relayWorker, d.paymaster, d.paymasterData, d.clientId);\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n virtual {\n (context, success, gasUseWithoutPost, relayData);\n }\n\n function versionPaymaster() external view override virtual returns (string memory){\n return \"3.0.0-beta.3+opengsn.vpm.ipaymaster\";\n }\n\n function setSigner(address _signer) public onlyOwner {\n signer = _signer;\n }\n}\n" + }, + "contracts-link/paymasters/WhitelistPaymaster.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma experimental ABIEncoderV2;\n\nimport \"@opengsn/contracts/src/BasePaymaster.sol\";\n\n/// A sample paymaster that has whitelists for senders, targets and methods.\n/// - if at least one sender is whitelisted, then ONLY whitelisted senders are allowed.\n/// - if at least one target is whitelisted, then ONLY whitelisted targets are allowed.\ncontract WhitelistPaymaster is BasePaymaster {\n\n bool public useSenderWhitelist;\n bool public useTargetWhitelist;\n bool public useMethodWhitelist;\n bool public useRejectOnRecipientRevert;\n mapping(address => bool) public senderWhitelist;\n mapping(address => bool) public targetWhitelist;\n mapping(address => mapping(bytes4 => bool)) public methodWhitelist;\n\n function versionPaymaster() external view override virtual returns (string memory){\n return \"3.0.0-beta.3+opengsn.whitelist.ipaymaster\";\n }\n\n function whitelistSender(address sender, bool isAllowed) public onlyOwner {\n senderWhitelist[sender] = isAllowed;\n }\n\n function whitelistTarget(address target, bool isAllowed) public onlyOwner {\n targetWhitelist[target] = isAllowed;\n }\n\n function whitelistMethod(address target, bytes4 method, bool isAllowed) public onlyOwner {\n methodWhitelist[target][method] = isAllowed;\n }\n\n function setConfiguration(\n bool _useSenderWhitelist,\n bool _useTargetWhitelist,\n bool _useMethodWhitelist,\n bool _useRejectOnRecipientRevert\n ) public onlyOwner {\n useSenderWhitelist = _useSenderWhitelist;\n useTargetWhitelist = _useTargetWhitelist;\n useMethodWhitelist = _useMethodWhitelist;\n useRejectOnRecipientRevert = _useRejectOnRecipientRevert;\n }\n\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n virtual\n returns (bytes memory context, bool revertOnRecipientRevert) {\n (signature, maxPossibleGas);\n require(approvalData.length == 0, \"approvalData: invalid length\");\n require(relayRequest.relayData.paymasterData.length == 0, \"paymasterData: invalid length\");\n\n if (useSenderWhitelist) {\n address sender = relayRequest.request.from;\n require(senderWhitelist[sender], \"sender not whitelisted\");\n }\n\n if (useTargetWhitelist) {\n address target = relayRequest.request.to;\n require(targetWhitelist[target], \"target not whitelisted\");\n }\n\n if (useMethodWhitelist) {\n address target = relayRequest.request.to;\n bytes4 method = GsnUtils.getMethodSig(relayRequest.request.data);\n require(methodWhitelist[target][method], \"method not whitelisted\");\n }\n\n return (\"\", useRejectOnRecipientRevert);\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n virtual {\n (context, success, gasUseWithoutPost, relayData);\n }\n}\n" + }, + "contracts-link/Penalizer.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\nimport \"./utils/RLPReader.sol\";\nimport \"./utils/GsnUtils.sol\";\nimport \"./interfaces/IRelayHub.sol\";\nimport \"./interfaces/IPenalizer.sol\";\n\n/**\n * @title The Penalizer Implementation\n *\n * @notice This Penalizer supports parsing Legacy, Type 1 and Type 2 raw RLP Encoded transactions.\n */\ncontract Penalizer is IPenalizer, ERC165 {\n using ECDSA for bytes32;\n\n /// @inheritdoc IPenalizer\n string public override versionPenalizer = \"3.0.0-beta.3+opengsn.penalizer.ipenalizer\";\n\n uint256 internal immutable penalizeBlockDelay;\n uint256 internal immutable penalizeBlockExpiration;\n\n constructor(\n uint256 _penalizeBlockDelay,\n uint256 _penalizeBlockExpiration\n ) {\n penalizeBlockDelay = _penalizeBlockDelay;\n penalizeBlockExpiration = _penalizeBlockExpiration;\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n return interfaceId == type(IPenalizer).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IPenalizer\n function getPenalizeBlockDelay() external override view returns (uint256) {\n return penalizeBlockDelay;\n }\n\n /// @inheritdoc IPenalizer\n function getPenalizeBlockExpiration() external override view returns (uint256) {\n return penalizeBlockExpiration;\n }\n\n function isLegacyTransaction(bytes calldata rawTransaction) internal pure returns (bool) {\n uint8 transactionTypeByte = uint8(rawTransaction[0]);\n return (transactionTypeByte >= 0xc0 && transactionTypeByte <= 0xfe);\n }\n\n function isTransactionType1(bytes calldata rawTransaction) internal pure returns (bool) {\n return (uint8(rawTransaction[0]) == 1);\n }\n\n function isTransactionType2(bytes calldata rawTransaction) internal pure returns (bool) {\n return (uint8(rawTransaction[0]) == 2);\n }\n\n /// @return `true` if raw transaction is of types Legacy, 1 or 2. `false` otherwise.\n function isTransactionTypeValid(bytes calldata rawTransaction) public pure returns(bool) {\n return isLegacyTransaction(rawTransaction) || isTransactionType1(rawTransaction) || isTransactionType2(rawTransaction);\n }\n\n /// @return transaction The details that the `Penalizer` needs to decide if the transaction is penalizable.\n function decodeTransaction(bytes calldata rawTransaction) public pure returns (Transaction memory transaction) {\n if (isTransactionType1(rawTransaction)) {\n (transaction.nonce,\n transaction.gasLimit,\n transaction.to,\n transaction.value,\n transaction.data) = RLPReader.decodeTransactionType1(rawTransaction);\n } else if (isTransactionType2(rawTransaction)) {\n (transaction.nonce,\n transaction.gasLimit,\n transaction.to,\n transaction.value,\n transaction.data) = RLPReader.decodeTransactionType2(rawTransaction);\n } else {\n (transaction.nonce,\n transaction.gasLimit,\n transaction.to,\n transaction.value,\n transaction.data) = RLPReader.decodeLegacyTransaction(rawTransaction);\n }\n return transaction;\n }\n\n mapping(bytes32 => uint256) public commits;\n\n /// @inheritdoc IPenalizer\n function commit(bytes32 commitHash) external override {\n uint256 readyBlockNumber = block.number + penalizeBlockDelay;\n commits[commitHash] = readyBlockNumber;\n emit CommitAdded(msg.sender, commitHash, readyBlockNumber);\n }\n\n /// Modifier that verifies there was a `commit` operation before this call that has not expired yet.\n modifier commitRevealOnly() {\n bytes32 commitHash = keccak256(abi.encodePacked(keccak256(msg.data), msg.sender));\n uint256 readyBlockNumber = commits[commitHash];\n delete commits[commitHash];\n // msg.sender can only be fake during off-chain view call, allowing Penalizer process to check transactions\n if(msg.sender != address(type(uint160).max)) {\n require(readyBlockNumber != 0, \"no commit\");\n require(readyBlockNumber < block.number, \"reveal penalize too soon\");\n require(readyBlockNumber + penalizeBlockExpiration > block.number, \"reveal penalize too late\");\n }\n _;\n }\n\n /// @inheritdoc IPenalizer\n function penalizeRepeatedNonce(\n bytes calldata unsignedTx1,\n bytes calldata signature1,\n bytes calldata unsignedTx2,\n bytes calldata signature2,\n IRelayHub hub,\n uint256 randomValue\n )\n public\n override\n commitRevealOnly {\n (randomValue);\n _penalizeRepeatedNonce(unsignedTx1, signature1, unsignedTx2, signature2, hub);\n }\n\n function _penalizeRepeatedNonce(\n bytes calldata unsignedTx1,\n bytes calldata signature1,\n bytes calldata unsignedTx2,\n bytes calldata signature2,\n IRelayHub hub\n )\n private\n {\n address addr1 = keccak256(unsignedTx1).recover(signature1);\n address addr2 = keccak256(unsignedTx2).recover(signature2);\n\n require(addr1 == addr2, \"Different signer\");\n require(addr1 != address(0), \"ecrecover failed\");\n\n Transaction memory decodedTx1 = decodeTransaction(unsignedTx1);\n Transaction memory decodedTx2 = decodeTransaction(unsignedTx2);\n\n // checking that the same nonce is used in both transaction, with both signed by the same address\n // and the actual data is different\n // note: we compare the hash of the tx to save gas over iterating both byte arrays\n require(decodedTx1.nonce == decodedTx2.nonce, \"Different nonce\");\n\n bytes memory dataToCheck1 =\n abi.encodePacked(decodedTx1.data, decodedTx1.gasLimit, decodedTx1.to, decodedTx1.value);\n\n bytes memory dataToCheck2 =\n abi.encodePacked(decodedTx2.data, decodedTx2.gasLimit, decodedTx2.to, decodedTx2.value);\n\n require(keccak256(dataToCheck1) != keccak256(dataToCheck2), \"tx is equal\");\n\n penalize(addr1, hub);\n }\n\n /// @inheritdoc IPenalizer\n function penalizeIllegalTransaction(\n bytes calldata unsignedTx,\n bytes calldata signature,\n IRelayHub hub,\n uint256 randomValue\n )\n public\n override\n commitRevealOnly {\n (randomValue);\n _penalizeIllegalTransaction(unsignedTx, signature, hub);\n }\n\n function _penalizeIllegalTransaction(\n bytes calldata unsignedTx,\n bytes calldata signature,\n IRelayHub hub\n )\n private\n {\n if (isTransactionTypeValid(unsignedTx)) {\n Transaction memory decodedTx = decodeTransaction(unsignedTx);\n if (decodedTx.to == address(hub)) {\n bytes4 selector = GsnUtils.getMethodSig(decodedTx.data);\n bool isWrongMethodCall = selector != IRelayHub.relayCall.selector;\n require(\n isWrongMethodCall,\n \"Legal relay transaction\");\n }\n }\n address relay = keccak256(unsignedTx).recover(signature);\n require(relay != address(0), \"ecrecover failed\");\n penalize(relay, hub);\n }\n\n function penalize(address relayWorker, IRelayHub hub) private {\n hub.penalize(relayWorker, payable(msg.sender));\n }\n}" + }, + "contracts-link/RelayHub.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable not-rely-on-time */\n/* solhint-disable avoid-tx-origin */\n/* solhint-disable bracket-align */\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"./utils/MinLibBytes.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"./utils/GsnUtils.sol\";\nimport \"./utils/GsnEip712Library.sol\";\nimport \"./utils/RelayHubValidator.sol\";\nimport \"./utils/GsnTypes.sol\";\nimport \"./interfaces/IRelayHub.sol\";\nimport \"./interfaces/IPaymaster.sol\";\nimport \"./forwarder/IForwarder.sol\";\nimport \"./interfaces/IStakeManager.sol\";\nimport \"./interfaces/IRelayRegistrar.sol\";\nimport \"./interfaces/IStakeManager.sol\";\n\n/**\n * @title The RelayHub Implementation\n * @notice This contract implements the `IRelayHub` interface for the EVM-compatible networks.\n */\ncontract RelayHub is IRelayHub, Ownable, ERC165 {\n using ERC165Checker for address;\n using Address for address;\n\n address private constant DRY_RUN_ADDRESS = 0x0000000000000000000000000000000000000000;\n\n /// @inheritdoc IRelayHub\n function versionHub() override virtual public pure returns (string memory){\n return \"3.0.0-beta.3+opengsn.hub.irelayhub\";\n }\n\n IStakeManager internal immutable stakeManager;\n address internal immutable penalizer;\n address internal immutable batchGateway;\n address internal immutable relayRegistrar;\n\n RelayHubConfig internal config;\n\n /// @inheritdoc IRelayHub\n function getConfiguration() public override view returns (RelayHubConfig memory) {\n return config;\n }\n\n /// @inheritdoc IRelayHub\n function setConfiguration(RelayHubConfig memory _config) public override onlyOwner {\n require(_config.devFee < 100, \"dev fee too high\");\n config = _config;\n emit RelayHubConfigured(config);\n }\n\n // maps ERC-20 token address to a minimum stake for it\n mapping(IERC20 => uint256) internal minimumStakePerToken;\n\n /// @inheritdoc IRelayHub\n function setMinimumStakes(IERC20[] memory token, uint256[] memory minimumStake) public override onlyOwner {\n require(token.length == minimumStake.length, \"setMinimumStakes: wrong length\");\n for (uint256 i = 0; i < token.length; i++) {\n minimumStakePerToken[token[i]] = minimumStake[i];\n emit StakingTokenDataChanged(address(token[i]), minimumStake[i]);\n }\n }\n\n // maps relay worker's address to its manager's address\n mapping(address => address) internal workerToManager;\n\n // maps relay managers to the number of their workers\n mapping(address => uint256) internal workerCount;\n\n mapping(address => uint256) internal balances;\n\n uint256 internal immutable creationBlock;\n uint256 internal deprecationTime = type(uint256).max;\n\n constructor (\n IStakeManager _stakeManager,\n address _penalizer,\n address _batchGateway,\n address _relayRegistrar,\n RelayHubConfig memory _config\n ) {\n creationBlock = block.number;\n stakeManager = _stakeManager;\n penalizer = _penalizer;\n batchGateway = _batchGateway;\n relayRegistrar = _relayRegistrar;\n setConfiguration(_config);\n }\n\n /// @inheritdoc IRelayHub\n function getCreationBlock() external override virtual view returns (uint256){\n return creationBlock;\n }\n\n /// @inheritdoc IRelayHub\n function getDeprecationTime() external override view returns (uint256) {\n return deprecationTime;\n }\n\n /// @inheritdoc IRelayHub\n function getStakeManager() external override view returns (IStakeManager) {\n return stakeManager;\n }\n\n /// @inheritdoc IRelayHub\n function getPenalizer() external override view returns (address) {\n return penalizer;\n }\n\n /// @inheritdoc IRelayHub\n function getBatchGateway() external override view returns (address) {\n return batchGateway;\n }\n\n /// @inheritdoc IRelayHub\n function getRelayRegistrar() external override view returns (address) {\n return relayRegistrar;\n }\n\n /// @inheritdoc IRelayHub\n function getMinimumStakePerToken(IERC20 token) external override view returns (uint256) {\n return minimumStakePerToken[token];\n }\n\n /// @inheritdoc IRelayHub\n function getWorkerManager(address worker) external override view returns (address) {\n return workerToManager[worker];\n }\n\n /// @inheritdoc IRelayHub\n function getWorkerCount(address manager) external override view returns (uint256) {\n return workerCount[manager];\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n return interfaceId == type(IRelayHub).interfaceId ||\n interfaceId == type(Ownable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IRelayHub\n function onRelayServerRegistered(address relayManager) external override {\n require(msg.sender == relayRegistrar, \"caller is not relay registrar\");\n verifyRelayManagerStaked(relayManager);\n require(workerCount[relayManager] > 0, \"no relay workers\");\n stakeManager.updateRelayKeepaliveTime(relayManager);\n }\n\n /// @inheritdoc IRelayHub\n function addRelayWorkers(address[] calldata newRelayWorkers) external override {\n address relayManager = msg.sender;\n uint256 newWorkerCount = workerCount[relayManager] + newRelayWorkers.length;\n workerCount[relayManager] = newWorkerCount;\n require(newWorkerCount <= config.maxWorkerCount, \"too many workers\");\n\n verifyRelayManagerStaked(relayManager);\n\n for (uint256 i = 0; i < newRelayWorkers.length; i++) {\n require(workerToManager[newRelayWorkers[i]] == address(0), \"this worker has a manager\");\n workerToManager[newRelayWorkers[i]] = relayManager;\n }\n\n emit RelayWorkersAdded(relayManager, newRelayWorkers, newWorkerCount);\n }\n\n /// @inheritdoc IRelayHub\n function depositFor(address target) public virtual override payable {\n require(target.supportsInterface(type(IPaymaster).interfaceId), \"target is not a valid IPaymaster\");\n uint256 amount = msg.value;\n\n balances[target] = balances[target] + amount;\n\n emit Deposited(target, msg.sender, amount);\n }\n\n /// @inheritdoc IRelayHub\n function balanceOf(address target) external override view returns (uint256) {\n return balances[target];\n }\n\n /// @inheritdoc IRelayHub\n function withdraw(address payable dest, uint256 amount) public override {\n uint256[] memory amounts = new uint256[](1);\n address payable[] memory destinations = new address payable[](1);\n amounts[0] = amount;\n destinations[0] = dest;\n withdrawMultiple(destinations, amounts);\n }\n\n /// @inheritdoc IRelayHub\n function withdrawMultiple(address payable[] memory dest, uint256[] memory amount) public override {\n address payable account = payable(msg.sender);\n for (uint256 i = 0; i < amount.length; i++) {\n uint256 balance = balances[account];\n require(balance >= amount[i], \"insufficient funds\");\n balances[account] = balance - amount[i];\n (bool success, ) = dest[i].call{value: amount[i]}(\"\");\n require(success, \"Transfer failed.\");\n emit Withdrawn(account, dest[i], amount[i]);\n }\n }\n\n function verifyGasAndDataLimits(\n uint256 maxAcceptanceBudget,\n GsnTypes.RelayRequest calldata relayRequest,\n uint256 initialGasLeft\n )\n private\n view\n returns (IPaymaster.GasAndDataLimits memory gasAndDataLimits, uint256 maxPossibleGas) {\n gasAndDataLimits =\n IPaymaster(relayRequest.relayData.paymaster).getGasAndDataLimits{gas:50000}();\n require(msg.data.length <= gasAndDataLimits.calldataSizeLimit, \"msg.data exceeded limit\" );\n\n require(maxAcceptanceBudget >= gasAndDataLimits.acceptanceBudget, \"acceptance budget too high\");\n require(gasAndDataLimits.acceptanceBudget >= gasAndDataLimits.preRelayedCallGasLimit, \"acceptance budget too low\");\n\n maxPossibleGas = relayRequest.relayData.transactionCalldataGasUsed + initialGasLeft;\n\n uint256 maxPossibleCharge = calculateCharge(\n maxPossibleGas,\n relayRequest.relayData\n );\n\n // We don't yet know how much gas will be used by the recipient, so we make sure there are enough funds to pay\n // for the maximum possible charge.\n require(maxPossibleCharge <= balances[relayRequest.relayData.paymaster],\n \"Paymaster balance too low\");\n }\n\n struct RelayCallData {\n bool success;\n bytes4 functionSelector;\n uint256 initialGasLeft;\n bytes recipientContext;\n bytes relayedCallReturnValue;\n IPaymaster.GasAndDataLimits gasAndDataLimits;\n RelayCallStatus status;\n uint256 innerGasUsed;\n uint256 maxPossibleGas;\n uint256 innerGasLimit;\n uint256 gasBeforeInner;\n uint256 gasUsed;\n uint256 devCharge;\n bytes retData;\n address relayManager;\n bytes32 relayRequestId;\n uint256 tmpInitialGas;\n bytes relayCallStatus;\n }\n\n /// @inheritdoc IRelayHub\n function relayCall(\n string calldata domainSeparatorName,\n uint256 maxAcceptanceBudget,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData\n )\n external\n override\n returns (\n bool paymasterAccepted,\n uint256 charge,\n IRelayHub.RelayCallStatus status,\n bytes memory returnValue)\n {\n RelayCallData memory vars;\n vars.initialGasLeft = aggregateGasleft();\n vars.relayRequestId = GsnUtils.getRelayRequestID(relayRequest, signature);\n\n require(!isDeprecated(), \"hub deprecated\");\n vars.functionSelector = relayRequest.request.data.length>=4 ? MinLibBytes.readBytes4(relayRequest.request.data, 0) : bytes4(0);\n\n if (msg.sender != batchGateway && tx.origin != DRY_RUN_ADDRESS) {\n require(signature.length != 0, \"missing signature or bad gateway\");\n require(msg.sender == tx.origin, \"relay worker must be EOA\");\n require(msg.sender == relayRequest.relayData.relayWorker, \"Not a right worker\");\n }\n\n if (tx.origin != DRY_RUN_ADDRESS) {\n vars.relayManager = workerToManager[relayRequest.relayData.relayWorker];\n require(vars.relayManager != address(0), \"Unknown relay worker\");\n verifyRelayManagerStaked(vars.relayManager);\n }\n\n (vars.gasAndDataLimits, vars.maxPossibleGas) =\n verifyGasAndDataLimits(maxAcceptanceBudget, relayRequest, vars.initialGasLeft);\n\n RelayHubValidator.verifyTransactionPacking(domainSeparatorName,relayRequest,signature,approvalData);\n\n {\n\n //How much gas to pass down to innerRelayCall. must be lower than the default 63/64\n // actually, min(gasleft*63/64, gasleft-GAS_RESERVE) might be enough.\n vars.innerGasLimit = gasleft()*63/64- config.gasReserve;\n vars.gasBeforeInner = aggregateGasleft();\n\n /*\n Preparing to calculate \"gasUseWithoutPost\":\n MPG = calldataGasUsage + vars.initialGasLeft :: max possible gas, an approximate gas limit for the current transaction\n GU1 = MPG - gasleft(called right before innerRelayCall) :: gas actually used by current transaction until that point\n GU2 = innerGasLimit - gasleft(called inside the innerRelayCall just before preRelayedCall) :: gas actually used by innerRelayCall before calling postRelayCall\n GWP1 = GU1 + GU2 :: gas actually used by the entire transaction before calling postRelayCall\n TGO = config.gasOverhead + config.postOverhead :: extra that will be added to the charge to cover hidden costs\n GWP = GWP1 + TGO :: transaction \"gas used without postRelayCall\"\n */\n vars.tmpInitialGas = relayRequest.relayData.transactionCalldataGasUsed + vars.initialGasLeft + vars.innerGasLimit + config.gasOverhead + config.postOverhead;\n // Calls to the recipient are performed atomically inside an inner transaction which may revert in case of\n // errors in the recipient. In either case (revert or regular execution) the return data encodes the\n // RelayCallStatus value.\n (vars.success, vars.relayCallStatus) = address(this).call{gas:vars.innerGasLimit}(\n abi.encodeWithSelector(RelayHub.innerRelayCall.selector, domainSeparatorName, relayRequest, signature, approvalData, vars.gasAndDataLimits,\n vars.tmpInitialGas - aggregateGasleft(), /* totalInitialGas */\n vars.maxPossibleGas\n )\n );\n vars.innerGasUsed = vars.gasBeforeInner-aggregateGasleft();\n (vars.status, vars.relayedCallReturnValue) = abi.decode(vars.relayCallStatus, (RelayCallStatus, bytes));\n if ( vars.relayedCallReturnValue.length>0 ) {\n emit TransactionResult(vars.status, vars.relayedCallReturnValue);\n }\n }\n {\n if (!vars.success) {\n //Failure cases where the PM doesn't pay\n if (vars.status == RelayCallStatus.RejectedByPreRelayed ||\n (vars.innerGasUsed <= vars.gasAndDataLimits.acceptanceBudget + relayRequest.relayData.transactionCalldataGasUsed) && (\n vars.status == RelayCallStatus.RejectedByForwarder ||\n vars.status == RelayCallStatus.RejectedByRecipientRevert //can only be thrown if rejectOnRecipientRevert==true\n )) {\n emit TransactionRejectedByPaymaster(\n vars.relayManager,\n relayRequest.relayData.paymaster,\n vars.relayRequestId,\n relayRequest.request.from,\n relayRequest.request.to,\n msg.sender,\n vars.functionSelector,\n vars.innerGasUsed,\n vars.relayedCallReturnValue);\n return (false, 0, vars.status, vars.relayedCallReturnValue);\n }\n }\n\n // We now perform the actual charge calculation, based on the measured gas used\n vars.gasUsed = relayRequest.relayData.transactionCalldataGasUsed + (vars.initialGasLeft - aggregateGasleft()) + config.gasOverhead;\n charge = calculateCharge(vars.gasUsed, relayRequest.relayData);\n vars.devCharge = calculateDevCharge(charge);\n\n balances[relayRequest.relayData.paymaster] = balances[relayRequest.relayData.paymaster] - charge;\n balances[vars.relayManager] = balances[vars.relayManager] + (charge - vars.devCharge);\n if (vars.devCharge > 0) { // save some gas in case of zero dev charge\n balances[config.devAddress] = balances[config.devAddress] + vars.devCharge;\n }\n\n {\n address from = relayRequest.request.from;\n address to = relayRequest.request.to;\n address paymaster = relayRequest.relayData.paymaster;\n emit TransactionRelayed(\n vars.relayManager,\n msg.sender,\n vars.relayRequestId,\n from,\n to,\n paymaster,\n vars.functionSelector,\n vars.status,\n charge);\n }\n\n // avoid variable size memory copying after gas calculation completed on-chain\n if (tx.origin == DRY_RUN_ADDRESS) {\n return (true, charge, vars.status, vars.relayedCallReturnValue);\n }\n return (true, charge, vars.status, \"\");\n }\n }\n\n struct InnerRelayCallData {\n uint256 initialGasLeft;\n uint256 gasUsedToCallInner;\n uint256 balanceBefore;\n bytes32 preReturnValue;\n bool relayedCallSuccess;\n bytes relayedCallReturnValue;\n bytes recipientContext;\n bytes data;\n bool rejectOnRecipientRevert;\n }\n\n /**\n * @notice This method can only by called by this `RelayHub`.\n * It wraps the execution of the `RelayRequest` in a revertable frame context.\n */\n function innerRelayCall(\n string calldata domainSeparatorName,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n IPaymaster.GasAndDataLimits calldata gasAndDataLimits,\n uint256 totalInitialGas,\n uint256 maxPossibleGas\n )\n external\n returns (RelayCallStatus, bytes memory)\n {\n InnerRelayCallData memory vars;\n vars.initialGasLeft = aggregateGasleft();\n vars.gasUsedToCallInner = totalInitialGas - gasleft();\n // A new gas measurement is performed inside innerRelayCall, since\n // due to EIP150 available gas amounts cannot be directly compared across external calls\n\n // This external function can only be called by RelayHub itself, creating an internal transaction. Calls to the\n // recipient (preRelayedCall, the relayedCall, and postRelayedCall) are called from inside this transaction.\n require(msg.sender == address(this), \"Must be called by RelayHub\");\n\n // If either pre or post reverts, the whole internal transaction will be reverted, reverting all side effects on\n // the recipient. The recipient will still be charged for the used gas by the relay.\n\n // The paymaster is no allowed to withdraw balance from RelayHub during a relayed transaction. We check pre and\n // post state to ensure this doesn't happen.\n vars.balanceBefore = balances[relayRequest.relayData.paymaster];\n\n // First preRelayedCall is executed.\n // Note: we open a new block to avoid growing the stack too much.\n vars.data = abi.encodeWithSelector(\n IPaymaster.preRelayedCall.selector,\n relayRequest, signature, approvalData, maxPossibleGas\n );\n {\n bool success;\n bytes memory retData;\n (success, retData) = relayRequest.relayData.paymaster.call{gas:gasAndDataLimits.preRelayedCallGasLimit}(vars.data);\n if (!success) {\n GsnEip712Library.truncateInPlace(retData);\n revertWithStatus(RelayCallStatus.RejectedByPreRelayed, retData);\n }\n (vars.recipientContext, vars.rejectOnRecipientRevert) = abi.decode(retData, (bytes,bool));\n }\n\n // The actual relayed call is now executed. The sender's address is appended at the end of the transaction data\n\n {\n bool forwarderSuccess;\n (forwarderSuccess, vars.relayedCallSuccess, vars.relayedCallReturnValue) = GsnEip712Library.execute(domainSeparatorName, relayRequest, signature);\n if ( !forwarderSuccess ) {\n revertWithStatus(RelayCallStatus.RejectedByForwarder, vars.relayedCallReturnValue);\n }\n\n if (vars.rejectOnRecipientRevert && !vars.relayedCallSuccess) {\n // we trusted the recipient, but it reverted...\n revertWithStatus(RelayCallStatus.RejectedByRecipientRevert, vars.relayedCallReturnValue);\n }\n }\n // Finally, postRelayedCall is executed, with the relayedCall execution's status and a charge estimate\n // We now determine how much the recipient will be charged, to pass this value to postRelayedCall for accurate\n // accounting.\n vars.data = abi.encodeWithSelector(\n IPaymaster.postRelayedCall.selector,\n vars.recipientContext,\n vars.relayedCallSuccess,\n vars.gasUsedToCallInner + (vars.initialGasLeft - aggregateGasleft()), /*gasUseWithoutPost*/\n relayRequest.relayData\n );\n\n {\n (bool successPost,bytes memory ret) = relayRequest.relayData.paymaster.call{gas:gasAndDataLimits.postRelayedCallGasLimit}(vars.data);\n\n if (!successPost) {\n revertWithStatus(RelayCallStatus.PostRelayedFailed, ret);\n }\n }\n\n if (balances[relayRequest.relayData.paymaster] < vars.balanceBefore) {\n revertWithStatus(RelayCallStatus.PaymasterBalanceChanged, \"\");\n }\n\n return (vars.relayedCallSuccess ? RelayCallStatus.OK : RelayCallStatus.RelayedCallFailed, vars.relayedCallReturnValue);\n }\n\n /**\n * @dev Reverts the transaction with return data set to the ABI encoding of the status argument (and revert reason data)\n */\n function revertWithStatus(RelayCallStatus status, bytes memory ret) private pure {\n bytes memory data = abi.encode(status, ret);\n GsnEip712Library.truncateInPlace(data);\n\n assembly {\n let dataSize := mload(data)\n let dataPtr := add(data, 32)\n\n revert(dataPtr, dataSize)\n }\n }\n\n /// @inheritdoc IRelayHub\n function calculateDevCharge(uint256 charge) public override virtual view returns (uint256){\n if (config.devFee == 0){ // save some gas in case of zero dev charge\n return 0;\n }\n unchecked {\n return charge * config.devFee / 100;\n }\n }\n\n /// @inheritdoc IRelayHub\n function calculateCharge(uint256 gasUsed, GsnTypes.RelayData calldata relayData) public override virtual view returns (uint256) {\n uint256 basefee;\n if (relayData.maxFeePerGas == relayData.maxPriorityFeePerGas) {\n basefee = 0;\n } else {\n basefee = block.basefee;\n }\n uint256 chargeableGasPrice = Math.min(relayData.maxFeePerGas, Math.min(tx.gasprice, basefee + relayData.maxPriorityFeePerGas));\n return config.baseRelayFee + (gasUsed * chargeableGasPrice * (config.pctRelayFee + 100)) / 100;\n }\n\n /// @inheritdoc IRelayHub\n function verifyRelayManagerStaked(address relayManager) public override view {\n (IStakeManager.StakeInfo memory info, bool isHubAuthorized) = stakeManager.getStakeInfo(relayManager);\n uint256 minimumStake = minimumStakePerToken[info.token];\n require(info.token != IERC20(address(0)), \"relay manager not staked\");\n require(info.stake >= minimumStake, \"stake amount is too small\");\n require(minimumStake != 0, \"staking this token is forbidden\");\n require(info.unstakeDelay >= config.minimumUnstakeDelay, \"unstake delay is too small\");\n require(info.withdrawTime == 0, \"stake has been withdrawn\");\n require(isHubAuthorized, \"this hub is not authorized by SM\");\n }\n\n /// @inheritdoc IRelayHub\n function deprecateHub(uint256 _deprecationTime) public override onlyOwner {\n require(!isDeprecated(), \"Already deprecated\");\n deprecationTime = _deprecationTime;\n emit HubDeprecated(deprecationTime);\n }\n\n /// @inheritdoc IRelayHub\n function isDeprecated() public override view returns (bool) {\n return block.timestamp >= deprecationTime;\n }\n\n /// @notice Prevents any address other than the `Penalizer` from calling this method.\n modifier penalizerOnly () {\n require(msg.sender == penalizer, \"Not penalizer\");\n _;\n }\n\n /// @inheritdoc IRelayHub\n function penalize(address relayWorker, address payable beneficiary) external override penalizerOnly {\n address relayManager = workerToManager[relayWorker];\n // The worker must be controlled by a manager with a locked stake\n require(relayManager != address(0), \"Unknown relay worker\");\n (IStakeManager.StakeInfo memory stakeInfo,) = stakeManager.getStakeInfo(relayManager);\n require(stakeInfo.stake > 0, \"relay manager not staked\");\n stakeManager.penalizeRelayManager(relayManager, beneficiary, stakeInfo.stake);\n }\n\n /// @inheritdoc IRelayHub\n function isRelayEscheatable(address relayManager) public view override returns (bool){\n return stakeManager.isRelayEscheatable(relayManager);\n }\n\n /// @inheritdoc IRelayHub\n function escheatAbandonedRelayBalance(address relayManager) external override onlyOwner {\n require(stakeManager.isRelayEscheatable(relayManager), \"relay server not escheatable yet\");\n uint256 balance = balances[relayManager];\n balances[relayManager] = 0;\n balances[config.devAddress] = balances[config.devAddress] + balance;\n emit AbandonedRelayManagerBalanceEscheated(relayManager, balance);\n }\n\n /// @inheritdoc IRelayHub\n function aggregateGasleft() public override virtual view returns (uint256){\n return gasleft();\n }\n}" + }, + "contracts-link/StakeManager.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// solhint-disable not-rely-on-time\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\nimport \"./interfaces/IStakeManager.sol\";\n\n/**\n * @title The StakeManager implementation\n * @notice An IStakeManager instance that accepts stakes in any ERC-20 token.\n *\n * @notice Single StakeInfo of a single RelayManager can only have one token address assigned to it.\n *\n * @notice It cannot be changed after the first time 'stakeForRelayManager' is called as it is equivalent to withdrawal.\n */\ncontract StakeManager is IStakeManager, Ownable, ERC165 {\n using SafeERC20 for IERC20;\n\n string public override versionSM = \"3.0.0-beta.3+opengsn.stakemanager.istakemanager\";\n uint256 internal immutable maxUnstakeDelay;\n\n AbandonedRelayServerConfig internal abandonedRelayServerConfig;\n\n address internal burnAddress;\n uint256 internal immutable creationBlock;\n\n /// maps relay managers to their stakes\n mapping(address => StakeInfo) public stakes;\n\n /// @inheritdoc IStakeManager\n function getStakeInfo(address relayManager) external override view returns (StakeInfo memory stakeInfo, bool isSenderAuthorizedHub) {\n bool isHubAuthorized = authorizedHubs[relayManager][msg.sender].removalTime == type(uint256).max;\n return (stakes[relayManager], isHubAuthorized);\n }\n\n /// @inheritdoc IStakeManager\n function setBurnAddress(address _burnAddress) public override onlyOwner {\n burnAddress = _burnAddress;\n emit BurnAddressSet(burnAddress);\n }\n\n /// @inheritdoc IStakeManager\n function getBurnAddress() external override view returns (address) {\n return burnAddress;\n }\n\n /// @inheritdoc IStakeManager\n function setDevAddress(address _devAddress) public override onlyOwner {\n abandonedRelayServerConfig.devAddress = _devAddress;\n emit DevAddressSet(abandonedRelayServerConfig.devAddress);\n }\n\n /// @inheritdoc IStakeManager\n function getAbandonedRelayServerConfig() external override view returns (AbandonedRelayServerConfig memory) {\n return abandonedRelayServerConfig;\n }\n\n /// @inheritdoc IStakeManager\n function getMaxUnstakeDelay() external override view returns (uint256) {\n return maxUnstakeDelay;\n }\n\n /// maps relay managers to a map of addressed of their authorized hubs to the information on that hub\n mapping(address => mapping(address => RelayHubInfo)) public authorizedHubs;\n\n constructor(\n uint256 _maxUnstakeDelay,\n uint256 _abandonmentDelay,\n uint256 _escheatmentDelay,\n address _burnAddress,\n address _devAddress\n ) {\n require(_burnAddress != address(0), \"transfers to address(0) may fail\");\n setBurnAddress(_burnAddress);\n setDevAddress(_devAddress);\n creationBlock = block.number;\n maxUnstakeDelay = _maxUnstakeDelay;\n abandonedRelayServerConfig.abandonmentDelay = _abandonmentDelay;\n abandonedRelayServerConfig.escheatmentDelay = _escheatmentDelay;\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n return interfaceId == type(IStakeManager).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IStakeManager\n function getCreationBlock() external override view returns (uint256){\n return creationBlock;\n }\n\n /// @inheritdoc IStakeManager\n function setRelayManagerOwner(address owner) external override {\n require(owner != address(0), \"invalid owner\");\n require(stakes[msg.sender].owner == address(0), \"already owned\");\n stakes[msg.sender].owner = owner;\n emit OwnerSet(msg.sender, owner);\n }\n\n /// @inheritdoc IStakeManager\n function stakeForRelayManager(IERC20 token, address relayManager, uint256 unstakeDelay, uint256 amount) external override relayOwnerOnly(relayManager) {\n require(unstakeDelay >= stakes[relayManager].unstakeDelay, \"unstakeDelay cannot be decreased\");\n require(unstakeDelay <= maxUnstakeDelay, \"unstakeDelay too big\");\n require(token != IERC20(address(0)), \"must specify stake token address\");\n require(\n stakes[relayManager].token == IERC20(address(0)) ||\n stakes[relayManager].token == token,\n \"stake token address is incorrect\");\n token.safeTransferFrom(msg.sender, address(this), amount);\n stakes[relayManager].token = token;\n stakes[relayManager].stake += amount;\n stakes[relayManager].unstakeDelay = unstakeDelay;\n emit StakeAdded(relayManager, stakes[relayManager].owner, stakes[relayManager].token, stakes[relayManager].stake, stakes[relayManager].unstakeDelay);\n }\n\n /// @inheritdoc IStakeManager\n function unlockStake(address relayManager) external override relayOwnerOnly(relayManager) {\n StakeInfo storage info = stakes[relayManager];\n require(info.withdrawTime == 0, \"already pending\");\n info.withdrawTime = block.timestamp + info.unstakeDelay;\n emit StakeUnlocked(relayManager, msg.sender, info.withdrawTime);\n }\n\n /// @inheritdoc IStakeManager\n function withdrawStake(address relayManager) external override relayOwnerOnly(relayManager) {\n StakeInfo storage info = stakes[relayManager];\n require(info.withdrawTime > 0, \"Withdrawal is not scheduled\");\n require(info.withdrawTime <= block.timestamp, \"Withdrawal is not due\");\n uint256 amount = info.stake;\n info.stake = 0;\n info.withdrawTime = 0;\n info.token.safeTransfer(msg.sender, amount);\n emit StakeWithdrawn(relayManager, msg.sender, info.token, amount);\n }\n\n /// @notice Prevents any address other than a registered Relay Owner from calling this method.\n modifier relayOwnerOnly (address relayManager) {\n StakeInfo storage info = stakes[relayManager];\n require(info.owner == msg.sender, \"not owner\");\n _;\n }\n\n /// @notice Prevents any address other than a registered Relay Manager from calling this method.\n modifier managerOnly () {\n StakeInfo storage info = stakes[msg.sender];\n require(info.owner != address(0), \"not manager\");\n _;\n }\n\n /// @inheritdoc IStakeManager\n function authorizeHubByOwner(address relayManager, address relayHub) external relayOwnerOnly(relayManager) override {\n _authorizeHub(relayManager, relayHub);\n }\n\n /// @inheritdoc IStakeManager\n function authorizeHubByManager(address relayHub) external managerOnly override {\n _authorizeHub(msg.sender, relayHub);\n }\n\n function _authorizeHub(address relayManager, address relayHub) internal {\n authorizedHubs[relayManager][relayHub].removalTime = type(uint256).max;\n emit HubAuthorized(relayManager, relayHub);\n }\n\n /// @inheritdoc IStakeManager\n function unauthorizeHubByOwner(address relayManager, address relayHub) external override relayOwnerOnly(relayManager) {\n _unauthorizeHub(relayManager, relayHub);\n }\n\n /// @inheritdoc IStakeManager\n function unauthorizeHubByManager(address relayHub) external override managerOnly {\n _unauthorizeHub(msg.sender, relayHub);\n }\n\n function _unauthorizeHub(address relayManager, address relayHub) internal {\n RelayHubInfo storage hubInfo = authorizedHubs[relayManager][relayHub];\n require(hubInfo.removalTime == type(uint256).max, \"hub not authorized\");\n hubInfo.removalTime = block.timestamp + stakes[relayManager].unstakeDelay;\n emit HubUnauthorized(relayManager, relayHub, hubInfo.removalTime);\n }\n\n /// @inheritdoc IStakeManager\n function penalizeRelayManager(address relayManager, address beneficiary, uint256 amount) external override {\n uint256 removalTime = authorizedHubs[relayManager][msg.sender].removalTime;\n require(removalTime != 0, \"hub not authorized\");\n require(removalTime > block.timestamp, \"hub authorization expired\");\n\n // Half of the stake will be burned (sent to address 0)\n require(stakes[relayManager].stake >= amount, \"penalty exceeds stake\");\n stakes[relayManager].stake =stakes[relayManager].stake - amount;\n\n uint256 toBurn = amount / 2;\n uint256 reward = amount - toBurn;\n\n // Stake ERC-20 token is burned and transferred\n stakes[relayManager].token.safeTransfer(burnAddress, toBurn);\n stakes[relayManager].token.safeTransfer(beneficiary, reward);\n emit StakePenalized(relayManager, beneficiary, stakes[relayManager].token, reward);\n }\n\n /// @inheritdoc IStakeManager\n function isRelayEscheatable(address relayManager) public view override returns (bool) {\n IStakeManager.StakeInfo memory stakeInfo = stakes[relayManager];\n return stakeInfo.abandonedTime != 0 && stakeInfo.abandonedTime + abandonedRelayServerConfig.escheatmentDelay < block.timestamp;\n }\n\n /// @inheritdoc IStakeManager\n function markRelayAbandoned(address relayManager) external override onlyOwner {\n StakeInfo storage info = stakes[relayManager];\n require(info.stake > 0, \"relay manager not staked\");\n require(info.abandonedTime == 0, \"relay manager already abandoned\");\n require(info.keepaliveTime + abandonedRelayServerConfig.abandonmentDelay < block.timestamp, \"relay manager was alive recently\");\n info.abandonedTime = block.timestamp;\n emit RelayServerAbandoned(relayManager, info.abandonedTime);\n }\n\n /// @inheritdoc IStakeManager\n function escheatAbandonedRelayStake(address relayManager) external override onlyOwner {\n StakeInfo storage info = stakes[relayManager];\n require(isRelayEscheatable(relayManager), \"relay server not escheatable yet\");\n uint256 amount = info.stake;\n info.stake = 0;\n info.withdrawTime = 0;\n info.token.safeTransfer(abandonedRelayServerConfig.devAddress, amount);\n emit AbandonedRelayManagerStakeEscheated(relayManager, msg.sender, info.token, amount);\n }\n\n /// @inheritdoc IStakeManager\n function updateRelayKeepaliveTime(address relayManager) external override {\n StakeInfo storage info = stakes[relayManager];\n bool isHubAuthorized = authorizedHubs[relayManager][msg.sender].removalTime == type(uint256).max;\n bool isRelayOwner = info.owner == msg.sender;\n require(isHubAuthorized || isRelayOwner, \"must be called by owner or hub\");\n info.abandonedTime = 0;\n info.keepaliveTime = block.timestamp;\n emit RelayServerKeepalive(relayManager, info.keepaliveTime);\n }\n}" + }, + "contracts-link/test/PayableWithEmit.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"@opengsn/contracts/src/ERC2771Recipient.sol\";\n\n//make sure that \"payable\" function that uses _msgSender() still works\n// (its not required to use _msgSender(), since the default function\n// will never be called through GSN, but still, if someone uses it,\n// it should work)\ncontract PayableWithEmit is ERC2771Recipient {\n\n event Received(address sender, uint256 value, uint256 gasleft);\n\n receive () external payable {\n\n emit Received(_msgSender(), msg.value, gasleft());\n }\n\n //helper: send value to another contract\n function doSend(address payable target) public payable {\n\n uint256 before = gasleft();\n // solhint-disable-next-line check-send-result\n bool success = target.send(msg.value);\n uint256 gasAfter = gasleft();\n emit GasUsed(before-gasAfter, success);\n }\n event GasUsed(uint256 gasUsed, bool success);\n}" + }, + "contracts-link/test/TestArbSys.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../arbitrum/ArbSys.sol\";\n\n/**\n* As there is no way to run Arbitrum chain locally, tests currently need to run on simple hardhat node.\n* If some behavior is needed from ArbSys, it has to be stubbed here.\n */\ncontract TestArbSys is ArbSys {\n\n /**\n * @notice Get Arbitrum block number (distinct from L1 block number; Arbitrum genesis block has block number 0)\n * @return block number as int\n */\n function arbBlockNumber() external override view returns (uint256){\n return block.number * 17;\n }\n\n function getStorageGasAvailable() external override view returns (uint256) {\n // we need some really large value as for gasleft but also one that does decrease on every call\n return gasleft() * 100;\n }\n}" + }, + "contracts-link/test/TestDecimalsToken.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier:MIT\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestDecimalsToken is ERC20 {\n\n constructor() ERC20(\"Test Token\", \"DEC\") {\n mint(100 ether);\n }\n\n function mint(uint256 amount) public {\n _mint(msg.sender, amount);\n }\n\n uint8 private _decimals;\n\n function decimals() public view virtual override returns (uint8) {\n return _decimals;\n }\n\n function setDecimals(uint8 _dec) public {\n _decimals = _dec;\n }\n}" + }, + "contracts-link/test/TestGatewayForwarder.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../forwarder/Forwarder.sol\";\n\ncontract TestGatewayForwarder is Forwarder {\n address public trustedRelayHub;\n\n function setTrustedRelayHub(address _trustedRelayHub) external {\n trustedRelayHub = _trustedRelayHub;\n }\n\n function _verifySig(\n ForwardRequest calldata req,\n bytes32 domainSeparator,\n bytes32 requestTypeHash,\n bytes calldata suffixData,\n bytes calldata sig)\n internal\n override\n view\n {\n // trustedRelayHub can only be called from a verified Gateway where the signatures are actually checked\n // note that if signature field is set, it will be verified in this Forwarder anyway\n if (msg.sender != trustedRelayHub || sig.length != 0) {\n super._verifySig(req, domainSeparator, requestTypeHash, suffixData, sig);\n }\n }\n}" + }, + "contracts-link/test/TestPaymasterConfigurableMisbehavior.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"./TestPaymasterEverythingAccepted.sol\";\n\ncontract TestPaymasterConfigurableMisbehavior is TestPaymasterEverythingAccepted {\n\n bool public withdrawDuringPostRelayedCall;\n bool public withdrawDuringPreRelayedCall;\n bool public returnInvalidErrorCode;\n bool public revertPostRelayCall;\n bool public outOfGasPre;\n bool public revertPreRelayCall;\n bool public revertPreRelayCallOnEvenBlocks;\n bool public greedyAcceptanceBudget;\n bool public expensiveGasLimits;\n\n function setWithdrawDuringPostRelayedCall(bool val) public {\n withdrawDuringPostRelayedCall = val;\n }\n function setWithdrawDuringPreRelayedCall(bool val) public {\n withdrawDuringPreRelayedCall = val;\n }\n function setReturnInvalidErrorCode(bool val) public {\n returnInvalidErrorCode = val;\n }\n function setRevertPostRelayCall(bool val) public {\n revertPostRelayCall = val;\n }\n function setRevertPreRelayCall(bool val) public {\n revertPreRelayCall = val;\n }\n function setRevertPreRelayCallOnEvenBlocks(bool val) public {\n revertPreRelayCallOnEvenBlocks = val;\n }\n function setOutOfGasPre(bool val) public {\n outOfGasPre = val;\n }\n\n function setGreedyAcceptanceBudget(bool val) public {\n greedyAcceptanceBudget = val;\n }\n function setExpensiveGasLimits(bool val) public {\n expensiveGasLimits = val;\n }\n\n // solhint-disable-next-line no-empty-blocks\n function _verifyApprovalData(bytes calldata approvalData) internal virtual override view {}\n\n // solhint-disable-next-line no-empty-blocks\n function _verifyPaymasterData(GsnTypes.RelayRequest calldata relayRequest) internal virtual override view {}\n\n // solhint-disable reason-string\n // contains comments that are checked in tests\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n returns (bytes memory, bool) {\n (relayRequest, signature, approvalData, maxPossibleGas);\n if (outOfGasPre) {\n uint256 i = 0;\n while (true) {\n i++;\n }\n }\n\n require(!returnInvalidErrorCode, \"invalid code\");\n\n if (withdrawDuringPreRelayedCall) {\n withdrawAllBalance();\n }\n if (revertPreRelayCall) {\n revert(\"You asked me to revert, remember?\");\n }\n if (revertPreRelayCallOnEvenBlocks && block.number % 2 == 0) {\n revert(\"You asked me to revert on even blocks, remember?\");\n }\n return (\"\", trustRecipientRevert);\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n {\n (context, success, gasUseWithoutPost, relayData);\n if (withdrawDuringPostRelayedCall) {\n withdrawAllBalance();\n }\n if (revertPostRelayCall) {\n revert(\"You asked me to revert, remember?\");\n }\n }\n\n /// leaving withdrawal public and unprotected\n function withdrawAllBalance() public returns (uint256) {\n require(address(relayHub) != address(0), \"relay hub address not set\");\n uint256 balance = relayHub.balanceOf(address(this));\n relayHub.withdraw(payable(address(this)), balance);\n return balance;\n }\n\n IPaymaster.GasAndDataLimits private limits = super.getGasAndDataLimits();\n\n function getGasAndDataLimits()\n public override view\n returns (IPaymaster.GasAndDataLimits memory) {\n\n if (expensiveGasLimits) {\n uint256 sum;\n //memory access is 700gas, so we waste ~50000\n for ( int256 i=0; i<100000; i+=700 ) {\n sum = sum + limits.acceptanceBudget;\n }\n }\n if (greedyAcceptanceBudget) {\n return IPaymaster.GasAndDataLimits(limits.acceptanceBudget * 9, limits.preRelayedCallGasLimit, limits.postRelayedCallGasLimit,\n limits.calldataSizeLimit);\n }\n return limits;\n }\n\n bool private trustRecipientRevert;\n\n function setGasLimits(uint256 acceptanceBudget, uint256 preRelayedCallGasLimit, uint256 postRelayedCallGasLimit) public {\n limits = IPaymaster.GasAndDataLimits(\n acceptanceBudget,\n preRelayedCallGasLimit,\n postRelayedCallGasLimit,\n limits.calldataSizeLimit\n );\n }\n\n function setTrustRecipientRevert(bool on) public {\n trustRecipientRevert = on;\n }\n\n // solhint-disable-next-line no-empty-blocks\n receive() external override payable {}\n}" + }, + "contracts-link/test/TestPaymasterEverythingAccepted.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../forwarder/IForwarder.sol\";\nimport \"../BasePaymaster.sol\";\n\ncontract TestPaymasterEverythingAccepted is BasePaymaster {\n\n function versionPaymaster() external view override virtual returns (string memory){\n return \"3.0.0-beta.3+opengsn.test-pea.ipaymaster\";\n }\n\n event SampleRecipientPreCall();\n event SampleRecipientPostCall(bool success, uint256 actualCharge);\n\n // solhint-disable-next-line no-empty-blocks\n function _verifyValue(GsnTypes.RelayRequest calldata) internal override view{}\n\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n virtual\n returns (bytes memory, bool) {\n (relayRequest, signature);\n (approvalData, maxPossibleGas);\n emit SampleRecipientPreCall();\n return (\"no revert here\",false);\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n virtual\n {\n (context, gasUseWithoutPost, relayData);\n emit SampleRecipientPostCall(success, gasUseWithoutPost);\n }\n\n function deposit() public payable {\n require(address(relayHub) != address(0), \"relay hub address not set\");\n relayHub.depositFor{value:msg.value}(address(this));\n }\n\n function withdrawAll(address payable destination) public {\n uint256 amount = relayHub.balanceOf(address(this));\n withdrawRelayHubDepositTo(amount, destination);\n }\n}" + }, + "contracts-link/test/TestPaymasterOwnerSignature.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\nimport \"./TestPaymasterEverythingAccepted.sol\";\n\ncontract TestPaymasterOwnerSignature is TestPaymasterEverythingAccepted {\n using ECDSA for bytes32;\n\n /**\n * @notice This demonstrates how dapps can provide an off-chain signatures to relayed transactions.\n */\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n view\n override\n returns (bytes memory, bool) {\n (signature, maxPossibleGas);\n\n address signer =\n keccak256(abi.encodePacked(\"I approve\", relayRequest.request.from))\n .toEthSignedMessageHash()\n .recover(approvalData);\n require(signer == owner(), \"test: not approved\");\n return (\"\",false);\n }\n}" + }, + "contracts-link/test/TestPaymasterPreconfiguredApproval.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"./TestPaymasterEverythingAccepted.sol\";\n\ncontract TestPaymasterPreconfiguredApproval is TestPaymasterEverythingAccepted {\n\n bytes public expectedApprovalData;\n\n function setExpectedApprovalData(bytes memory val) public {\n expectedApprovalData = val;\n }\n\n function _verifyApprovalData(bytes calldata approvalData) internal override view {\n require(keccak256(expectedApprovalData) == keccak256(approvalData),\n string(abi.encodePacked(\n \"test: unexpected approvalData: '\", approvalData, \"' instead of '\", expectedApprovalData, \"'\")));\n }\n\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n view\n override\n returns (bytes memory, bool) {\n (relayRequest, signature, approvalData, maxPossibleGas);\n return (\"\",false);\n }\n}" + }, + "contracts-link/test/TestPaymasterStoreContext.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"./TestPaymasterEverythingAccepted.sol\";\n\ncontract TestPaymasterStoreContext is TestPaymasterEverythingAccepted {\n\n event SampleRecipientPreCallWithValues(\n address relay,\n address from,\n bytes encodedFunction,\n uint256 baseRelayFee,\n uint256 gasLimit,\n bytes approvalData,\n uint256 maxPossibleGas\n );\n\n event SampleRecipientPostCallWithValues(\n string context\n );\n\n /**\n * This demonstrates how preRelayedCall can return 'context' data for reuse in postRelayedCall.\n */\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n returns (bytes memory, bool) {\n (signature, approvalData, maxPossibleGas);\n\n emit SampleRecipientPreCallWithValues(\n relayRequest.relayData.relayWorker,\n relayRequest.request.from,\n relayRequest.request.data,\n relayRequest.relayData.maxFeePerGas,\n relayRequest.request.gas,\n approvalData,\n maxPossibleGas);\n return (\"context passed from preRelayedCall to postRelayedCall\",false);\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n {\n (context, success, gasUseWithoutPost, relayData);\n emit SampleRecipientPostCallWithValues(string(context));\n }\n}" + }, + "contracts-link/test/TestPaymasterVariableGasLimits.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"./TestPaymasterEverythingAccepted.sol\";\n\ncontract TestPaymasterVariableGasLimits is TestPaymasterEverythingAccepted {\n\n string public override versionPaymaster = \"3.0.0-beta.3+opengsn.test-vgl.ipaymaster\";\n\n event SampleRecipientPreCallWithValues(\n uint256 gasleft,\n uint256 maxPossibleGas\n );\n\n event SampleRecipientPostCallWithValues(\n uint256 gasleft,\n uint256 gasUseWithoutPost\n );\n\n function _preRelayedCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData,\n uint256 maxPossibleGas\n )\n internal\n override\n returns (bytes memory, bool) {\n (relayRequest, signature, approvalData);\n emit SampleRecipientPreCallWithValues(\n gasleft(), maxPossibleGas);\n return (\"\", false);\n }\n\n function _postRelayedCall(\n bytes calldata context,\n bool success,\n uint256 gasUseWithoutPost,\n GsnTypes.RelayData calldata relayData\n )\n internal\n override\n {\n (context, success, gasUseWithoutPost, relayData);\n emit SampleRecipientPostCallWithValues(gasleft(), gasUseWithoutPost);\n }\n}" + }, + "contracts-link/test/TestRecipient.sol": { + "content": "pragma solidity ^0.8.0;\n\n/* solhint-disable avoid-tx-origin */\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../utils/GsnUtils.sol\";\nimport \"../ERC2771Recipient.sol\";\nimport \"./TestPaymasterConfigurableMisbehavior.sol\";\n\ncontract TestRecipient is ERC2771Recipient {\n\n constructor(address forwarder) {\n _setTrustedForwarder(forwarder);\n }\n\n // testing inner call gas estimation\n uint256 private nothing1;\n uint256 private nothing2;\n uint256 private nothing3;\n // solhint-disable-next-line no-complex-fallback\n fallback() external payable {\n nothing1 = type(uint256).max;\n nothing2 = type(uint256).max;\n nothing3 = type(uint256).max;\n }\n\n event Reverting(string message);\n\n function testRevert() public {\n require(address(this) == address(0), \"always fail\");\n emit Reverting(\"if you see this revert failed...\");\n }\n\n address payable public paymaster;\n\n function setWithdrawDuringRelayedCall(address payable _paymaster) public {\n paymaster = _paymaster;\n }\n\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n\n event SampleRecipientEmitted(string message, address realSender, address msgSender, address origin, uint256 msgValue, uint256 gasLeft, uint256 balance);\n\n function recipientRevert() public {\n revert(\"this method reverts consistently\");\n }\n\n function emitMessage(string memory message) public payable returns (string memory) {\n uint256 gasLeft = gasleft();\n if (paymaster != address(0)) {\n withdrawAllBalance();\n }\n\n emit SampleRecipientEmitted(message, _msgSender(), msg.sender, tx.origin, msg.value, gasLeft, address(this).balance);\n return \"emitMessage return value\";\n }\n\n function withdrawAllBalance() public {\n TestPaymasterConfigurableMisbehavior(paymaster).withdrawAllBalance();\n }\n\n // solhint-disable-next-line no-empty-blocks\n function dontEmitMessage(string calldata message) public {}\n\n function emitMessageNoParams() public {\n emit SampleRecipientEmitted(\"Method with no parameters\", _msgSender(), msg.sender, tx.origin, 0, gasleft(), address(this).balance);\n }\n\n //return (or revert) with a string in the given length\n function checkReturnValues(uint256 len, bool doRevert) public view returns (string memory) {\n (this);\n string memory mesg = \"this is a long message that we are going to return a small part from. we don't use a loop since we want a fixed gas usage of the method itself.\";\n require( bytes(mesg).length>=len, \"invalid len: too large\");\n\n /* solhint-disable no-inline-assembly */\n //cut the msg at that length\n assembly { mstore(mesg, len) }\n require(!doRevert, mesg);\n return mesg;\n }\n\n //function with no return value (also test revert with no msg.\n function checkNoReturnValues(bool doRevert) public view {\n (this);\n /* solhint-disable reason-string*/\n require(!doRevert);\n }\n\n function withdrawFromSingletonWhitelistPaymaster(address payable singletonPaymaster) public {\n TestRecipient(singletonPaymaster).withdrawBalance(1);\n }\n\n // only here for one method sig\n // solhint-disable-next-line no-empty-blocks\n function withdrawBalance(uint256 amount) public {}\n\n // only here for one method sig\n // solhint-disable-next-line no-empty-blocks\n function captureTheFlag() external {}\n}" + }, + "contracts-link/test/TestRecipientWithoutFallback.sol": { + "content": "pragma solidity ^0.8.0;\n\n/* solhint-disable avoid-tx-origin */\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../utils/GsnUtils.sol\";\nimport \"../ERC2771Recipient.sol\";\nimport \"./TestPaymasterConfigurableMisbehavior.sol\";\n\ncontract TestRecipientWithoutFallback is ERC2771Recipient {\n\n constructor(address forwarder) {\n _setTrustedForwarder(forwarder);\n }\n}" + }, + "contracts-link/test/TestRelayHub.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../RelayHub.sol\";\n\ncontract TestRelayHub is RelayHub {\n\n constructor(\n IStakeManager _stakeManager,\n address _penalizer,\n address _batchGateway,\n address _relayRegistrar,\n RelayHubConfig memory _config\n // solhint-disable-next-line no-empty-blocks\n ) RelayHub(_stakeManager, _penalizer, _batchGateway, _relayRegistrar, _config) {}\n\n /// Allow depositing for non-paymaster addresses for Gas Calculations tests\n function depositFor(address target) public override payable {\n uint256 amount = msg.value;\n balances[target] = balances[target] + amount;\n emit Deposited(target, msg.sender, amount);\n }\n}" + }, + "contracts-link/test/TestRelayHubForRegistrar.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../RelayHub.sol\";\n\ncontract TestRelayHubForRegistrar {\n mapping(address => bool) public isStaked;\n\n function setRelayManagerStaked(address relayManager, bool _isStaked) external {\n isStaked[relayManager] = _isStaked;\n }\n\n function verifyCanRegister(address relayManager) external view {\n require(isStaked[relayManager], \"verifyCanRegister: cannot\");\n }\n\n function verifyRelayManagerStaked(address relayManager) external view {\n require(isStaked[relayManager], \"verifyRelayManagerStaked: is not\");\n }\n\n function onRelayServerRegistered(address relayManager) external view {\n require(isStaked[relayManager], \"onRelayServerRegistered no stake\");\n }\n}" + }, + "contracts-link/test/TestRelayHubValidator.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../utils/RelayHubValidator.sol\";\n\ncontract TestRelayHubValidator {\n\n //for testing purposes, we must be called from a method with same param signature as RelayCall\n function dummyRelayCall(\n string calldata domainSeparatorName,\n uint256, //paymasterMaxAcceptanceBudget,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData\n ) external {\n RelayHubValidator.verifyTransactionPacking(domainSeparatorName, relayRequest, signature, approvalData);\n }\n\n // helper method for verifyTransactionPacking\n function dynamicParamSize(bytes calldata buf) external pure returns (uint256) {\n return RelayHubValidator.dynamicParamSize(buf);\n }\n}" + }, + "contracts-link/test/TestRelayWorkerContract.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n/* solhint-disable avoid-tx-origin */\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../interfaces/IRelayHub.sol\";\n\ncontract TestRelayWorkerContract {\n\n function relayCall(\n IRelayHub hub,\n uint256 maxAcceptanceBudget,\n GsnTypes.RelayRequest memory relayRequest,\n bytes memory signature)\n public\n {\n hub.relayCall(\"GSN Relayed Transaction\", maxAcceptanceBudget, relayRequest, signature, \"\");\n }\n}" + }, + "contracts-link/test/TestToken.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier:MIT\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n\n constructor() ERC20(\"Test Token\", \"TOK\") {\n mint(100 ether);\n }\n\n function mint(uint256 amount) public {\n _mint(msg.sender, amount);\n }\n}" + }, + "contracts-link/test/TestUtil.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\nimport \"../utils/GsnTypes.sol\";\nimport \"../utils/GsnEip712Library.sol\";\nimport \"../utils/GsnUtils.sol\";\n\ncontract TestUtil {\n using ECDSA for bytes;\n using ECDSA for bytes32;\n\n function libRelayRequestName() public pure returns (string memory) {\n return GsnEip712Library.RELAY_REQUEST_NAME;\n }\n\n function libRelayRequestType() public pure returns (string memory) {\n return string(GsnEip712Library.RELAY_REQUEST_TYPE);\n }\n\n function libRelayRequestTypeHash() public pure returns (bytes32) {\n return GsnEip712Library.RELAY_REQUEST_TYPEHASH;\n }\n\n function libRelayRequestSuffix() public pure returns (string memory) {\n return GsnEip712Library.RELAY_REQUEST_SUFFIX;\n }\n\n //helpers for test to call the library funcs:\n function callForwarderVerify(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature\n )\n external\n view {\n GsnEip712Library.verify(\"GSN Relayed Transaction\", relayRequest, signature);\n }\n\n function callForwarderVerifyAndCall(\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature\n )\n external\n returns (\n bool success,\n bytes memory ret\n ) {\n bool forwarderSuccess;\n (forwarderSuccess, success, ret) = GsnEip712Library.execute(\"GSN Relayed Transaction\", relayRequest, signature);\n if (!forwarderSuccess) {\n GsnUtils.revertWithData(ret);\n }\n emit Called(success, success == false ? ret : bytes(\"\"));\n }\n\n event Called(bool success, bytes error);\n\n function splitRequest(\n GsnTypes.RelayRequest calldata relayRequest\n )\n external\n pure\n returns (\n bytes32 typeHash,\n bytes memory suffixData\n ) {\n (suffixData) = GsnEip712Library.splitRequest(relayRequest);\n typeHash = GsnEip712Library.RELAY_REQUEST_TYPEHASH;\n }\n\n function libDomainSeparator(address forwarder) public view returns (bytes32) {\n return GsnEip712Library.domainSeparator(\"GSN Relayed Transaction\", forwarder);\n }\n\n function libGetChainID() public view returns (uint256) {\n return GsnEip712Library.getChainID();\n }\n\n function _ecrecover(string memory message, bytes memory signature) public pure returns (address) {\n return bytes(message).toEthSignedMessageHash().recover(signature);\n }\n}" + }, + "contracts-link/test/TestWrappedNativeToken.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier:MIT\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"../interfaces/IERC20Token.sol\";\n\n/**\n * @notice minimal \"wrapped eth\" implementation.\n */\ncontract TestWrappedNativeToken is ERC20, IERC20Token {\n\n // solhint-disable-next-line no-empty-blocks\n constructor() ERC20(\"Wrapped Native Token\", \"wnTok\") {\n }\n\n receive() external payable {\n deposit();\n }\n\n function deposit() public override payable {\n _mint(msg.sender, msg.value);\n }\n\n function withdraw(uint256 amount) public override {\n _burn(msg.sender, amount);\n // solhint-disable-next-line avoid-low-level-calls\n (bool success,) = msg.sender.call{value:amount}(\"\");\n require(success, \"transfer failed\");\n }\n}" + }, + "contracts-link/utils/GsnEip712Library.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../utils/GsnTypes.sol\";\nimport \"../interfaces/IERC2771Recipient.sol\";\nimport \"../forwarder/IForwarder.sol\";\n\nimport \"./GsnUtils.sol\";\n\n/**\n * @title The ERC-712 Library for GSN\n * @notice Bridge Library to convert a GSN RelayRequest into a valid `ForwardRequest` for a `Forwarder`.\n */\nlibrary GsnEip712Library {\n // maximum length of return value/revert reason for 'execute' method. Will truncate result if exceeded.\n uint256 private constant MAX_RETURN_SIZE = 1024;\n\n //copied from Forwarder (can't reference string constants even from another library)\n string public constant GENERIC_PARAMS = \"address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data,uint256 validUntilTime\";\n\n bytes public constant RELAYDATA_TYPE = \"RelayData(uint256 maxFeePerGas,uint256 maxPriorityFeePerGas,uint256 transactionCalldataGasUsed,address relayWorker,address paymaster,address forwarder,bytes paymasterData,uint256 clientId)\";\n\n string public constant RELAY_REQUEST_NAME = \"RelayRequest\";\n string public constant RELAY_REQUEST_SUFFIX = string(abi.encodePacked(\"RelayData relayData)\", RELAYDATA_TYPE));\n\n bytes public constant RELAY_REQUEST_TYPE = abi.encodePacked(\n RELAY_REQUEST_NAME,\"(\",GENERIC_PARAMS,\",\", RELAY_REQUEST_SUFFIX);\n\n bytes32 public constant RELAYDATA_TYPEHASH = keccak256(RELAYDATA_TYPE);\n bytes32 public constant RELAY_REQUEST_TYPEHASH = keccak256(RELAY_REQUEST_TYPE);\n\n struct EIP712Domain {\n string name;\n string version;\n uint256 chainId;\n address verifyingContract;\n }\n\n bytes32 public constant EIP712DOMAIN_TYPEHASH = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n\n function splitRequest(\n GsnTypes.RelayRequest calldata req\n )\n internal\n pure\n returns (\n bytes memory suffixData\n ) {\n suffixData = abi.encode(\n hashRelayData(req.relayData));\n }\n\n //verify that the recipient trusts the given forwarder\n // MUST be called by paymaster\n function verifyForwarderTrusted(GsnTypes.RelayRequest calldata relayRequest) internal view {\n (bool success, bytes memory ret) = relayRequest.request.to.staticcall(\n abi.encodeWithSelector(\n IERC2771Recipient.isTrustedForwarder.selector, relayRequest.relayData.forwarder\n )\n );\n require(success, \"isTrustedForwarder: reverted\");\n require(ret.length == 32, \"isTrustedForwarder: bad response\");\n require(abi.decode(ret, (bool)), \"invalid forwarder for recipient\");\n }\n\n function verifySignature(\n string memory domainSeparatorName,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature\n ) internal view {\n (bytes memory suffixData) = splitRequest(relayRequest);\n bytes32 _domainSeparator = domainSeparator(domainSeparatorName, relayRequest.relayData.forwarder);\n IForwarder forwarder = IForwarder(payable(relayRequest.relayData.forwarder));\n forwarder.verify(relayRequest.request, _domainSeparator, RELAY_REQUEST_TYPEHASH, suffixData, signature);\n }\n\n function verify(\n string memory domainSeparatorName,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature\n ) internal view {\n verifyForwarderTrusted(relayRequest);\n verifySignature(domainSeparatorName, relayRequest, signature);\n }\n\n function execute(\n string memory domainSeparatorName,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature\n ) internal returns (\n bool forwarderSuccess,\n bool callSuccess,\n bytes memory ret\n ) {\n (bytes memory suffixData) = splitRequest(relayRequest);\n bytes32 _domainSeparator = domainSeparator(domainSeparatorName, relayRequest.relayData.forwarder);\n /* solhint-disable-next-line avoid-low-level-calls */\n (forwarderSuccess, ret) = relayRequest.relayData.forwarder.call(\n abi.encodeWithSelector(IForwarder.execute.selector,\n relayRequest.request, _domainSeparator, RELAY_REQUEST_TYPEHASH, suffixData, signature\n ));\n if ( forwarderSuccess ) {\n\n //decode return value of execute:\n (callSuccess, ret) = abi.decode(ret, (bool, bytes));\n }\n truncateInPlace(ret);\n }\n\n //truncate the given parameter (in-place) if its length is above the given maximum length\n // do nothing otherwise.\n //NOTE: solidity warns unless the method is marked \"pure\", but it DOES modify its parameter.\n function truncateInPlace(bytes memory data) internal pure {\n MinLibBytes.truncateInPlace(data, MAX_RETURN_SIZE);\n }\n\n function domainSeparator(string memory name, address forwarder) internal view returns (bytes32) {\n return hashDomain(EIP712Domain({\n name : name,\n version : \"3\",\n chainId : getChainID(),\n verifyingContract : forwarder\n }));\n }\n\n function getChainID() internal view returns (uint256 id) {\n /* solhint-disable no-inline-assembly */\n assembly {\n id := chainid()\n }\n }\n\n function hashDomain(EIP712Domain memory req) internal pure returns (bytes32) {\n return keccak256(abi.encode(\n EIP712DOMAIN_TYPEHASH,\n keccak256(bytes(req.name)),\n keccak256(bytes(req.version)),\n req.chainId,\n req.verifyingContract));\n }\n\n function hashRelayData(GsnTypes.RelayData calldata req) internal pure returns (bytes32) {\n return keccak256(abi.encode(\n RELAYDATA_TYPEHASH,\n req.maxFeePerGas,\n req.maxPriorityFeePerGas,\n req.transactionCalldataGasUsed,\n req.relayWorker,\n req.paymaster,\n req.forwarder,\n keccak256(req.paymasterData),\n req.clientId\n ));\n }\n}" + }, + "contracts-link/utils/GsnTypes.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../forwarder/IForwarder.sol\";\n\ninterface GsnTypes {\n /// @notice maxFeePerGas, maxPriorityFeePerGas, pctRelayFee and baseRelayFee must be validated inside of the paymaster's preRelayedCall in order not to overpay\n struct RelayData {\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n uint256 transactionCalldataGasUsed;\n address relayWorker;\n address paymaster;\n address forwarder;\n bytes paymasterData;\n uint256 clientId;\n }\n\n //note: must start with the ForwardRequest to be an extension of the generic forwarder\n struct RelayRequest {\n IForwarder.ForwardRequest request;\n RelayData relayData;\n }\n}" + }, + "contracts-link/utils/GsnUtils.sol": { + "content": "pragma solidity ^0.8.0;\n\n/* solhint-disable no-inline-assembly */\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../utils/MinLibBytes.sol\";\nimport \"./GsnTypes.sol\";\n\n/**\n * @title The GSN Solidity Utils Library\n * @notice Some library functions used throughout the GSN Solidity codebase.\n */\nlibrary GsnUtils {\n\n bytes32 constant private RELAY_REQUEST_ID_MASK = 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n\n /**\n * @notice Calculate an identifier for the meta-transaction in a format similar to a transaction hash.\n * Note that uniqueness relies on signature and may not be enforced if meta-transactions are verified\n * with a different algorithm, e.g. when batching.\n * @param relayRequest The `RelayRequest` for which an ID is being calculated.\n * @param signature The signature for the `RelayRequest`. It is not validated here and may even remain empty.\n */\n function getRelayRequestID(GsnTypes.RelayRequest calldata relayRequest, bytes calldata signature)\n internal\n pure\n returns (bytes32) {\n return keccak256(abi.encode(relayRequest.request.from, relayRequest.request.nonce, signature)) & RELAY_REQUEST_ID_MASK;\n }\n\n /**\n * @notice Extract the method identifier signature from the encoded function call.\n */\n function getMethodSig(bytes memory msgData) internal pure returns (bytes4) {\n return MinLibBytes.readBytes4(msgData, 0);\n }\n\n /**\n * @notice Extract a parameter from encoded-function block.\n * see: https://solidity.readthedocs.io/en/develop/abi-spec.html#formal-specification-of-the-encoding\n * The return value should be casted to the right type (`uintXXX`/`bytesXXX`/`address`/`bool`/`enum`).\n * @param msgData Byte array containing a uint256 value.\n * @param index Index in byte array of uint256 value.\n * @return result uint256 value from byte array.\n */\n function getParam(bytes memory msgData, uint256 index) internal pure returns (uint256 result) {\n return MinLibBytes.readUint256(msgData, 4 + index * 32);\n }\n\n /// @notice Re-throw revert with the same revert data.\n function revertWithData(bytes memory data) internal pure {\n assembly {\n revert(add(data,32), mload(data))\n }\n }\n\n}" + }, + "contracts-link/utils/MinLibBytes.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier: MIT\n// minimal bytes manipulation required by GSN\n// a minimal subset from 0x/LibBytes\n/* solhint-disable no-inline-assembly */\n\nlibrary MinLibBytes {\n\n //truncate the given parameter (in-place) if its length is above the given maximum length\n // do nothing otherwise.\n //NOTE: solidity warns unless the method is marked \"pure\", but it DOES modify its parameter.\n function truncateInPlace(bytes memory data, uint256 maxlen) internal pure {\n if (data.length > maxlen) {\n assembly { mstore(data, maxlen) }\n }\n }\n\n /// @dev Reads an address from a position in a byte array.\n /// @param b Byte array containing an address.\n /// @param index Index in byte array of address.\n /// @return result address from byte array.\n function readAddress(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (address result)\n {\n require (b.length >= index + 20, \"readAddress: data too short\");\n\n // Add offset to index:\n // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)\n // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)\n index += 20;\n\n // Read address from array memory\n assembly {\n // 1. Add index to address of bytes array\n // 2. Load 32-byte word from memory\n // 3. Apply 20-byte mask to obtain address\n result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)\n }\n return result;\n }\n\n function readBytes32(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes32 result)\n {\n require(b.length >= index + 32, \"readBytes32: data too short\" );\n\n // Read the bytes32 from array memory\n assembly {\n result := mload(add(b, add(index,32)))\n }\n return result;\n }\n\n /// @dev Reads a uint256 value from a position in a byte array.\n /// @param b Byte array containing a uint256 value.\n /// @param index Index in byte array of uint256 value.\n /// @return result uint256 value from byte array.\n function readUint256(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (uint256 result)\n {\n result = uint256(readBytes32(b, index));\n return result;\n }\n\n function readBytes4(\n bytes memory b,\n uint256 index\n )\n internal\n pure\n returns (bytes4 result)\n {\n require(b.length >= index + 4, \"readBytes4: data too short\");\n\n // Read the bytes4 from array memory\n assembly {\n result := mload(add(b, add(index,32)))\n // Solidity does not require us to clean the trailing bytes.\n // We do it anyway\n result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)\n }\n return result;\n }\n}" + }, + "contracts-link/utils/RelayHubValidator.sol": { + "content": "pragma solidity ^0.8.0;\npragma abicoder v2;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../utils/GsnTypes.sol\";\n\n/**\n * @title The RelayHub Validator Library\n * @notice Validates the `msg.data` received by the `RelayHub` does not contain unnecessary bytes.\n * Including these extra bytes would allow the Relay Server to inflate transaction costs and overcharge the client.\n */\nlibrary RelayHubValidator {\n\n /// @notice Validate that encoded `relayCall` is properly packed without any extra bytes\n function verifyTransactionPacking(\n string calldata domainSeparatorName,\n GsnTypes.RelayRequest calldata relayRequest,\n bytes calldata signature,\n bytes calldata approvalData\n ) internal pure {\n // abicoder v2: https://docs.soliditylang.org/en/latest/abi-spec.html\n // each static param/member is 1 word\n // struct (with dynamic members) has offset to struct which is 1 word\n // dynamic member is 1 word offset to actual value, which is 1-word length and ceil(length/32) words for data\n // relayCall has 5 method params,\n // relayRequest: 2 members\n // relayData 8 members\n // ForwardRequest: 7 members\n // total 21 32-byte words if all dynamic params are zero-length.\n uint256 expectedMsgDataLen = 4 + 22 * 32 +\n dynamicParamSize(bytes(domainSeparatorName)) +\n dynamicParamSize(signature) +\n dynamicParamSize(approvalData) +\n dynamicParamSize(relayRequest.request.data) +\n dynamicParamSize(relayRequest.relayData.paymasterData);\n // zero-length signature is allowed in a batch relay transaction\n require(expectedMsgDataLen == msg.data.length, \"extra msg.data bytes\" );\n }\n\n // helper method for verifyTransactionPacking:\n // size (in bytes) of the given \"bytes\" parameter. size include the length (32-byte word),\n // and actual data size, rounded up to full 32-byte words\n function dynamicParamSize(bytes calldata buf) internal pure returns (uint256) {\n return 32 + ((buf.length + 31) & (type(uint256).max - 31));\n }\n}" + }, + "contracts-link/utils/RelayRegistrar.sol": { + "content": "pragma solidity ^0.8.6;\n\n// solhint-disable not-rely-on-time\n//SPDX-License-Identifier: GPL-3.0-only\n\n/* solhint-disable no-inline-assembly */\n\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./MinLibBytes.sol\";\nimport \"../interfaces/IRelayHub.sol\";\nimport \"../interfaces/IRelayRegistrar.sol\";\n\n/**\n * @title The RelayRegistrar Implementation\n * @notice Keeps a list of registered relayers.\n *\n * @notice Provides view functions to read the list of registered relayers and filters out invalid ones.\n *\n * @notice Protects the list from spamming entries: only staked relayers are added.\n */\ncontract RelayRegistrar is IRelayRegistrar, Ownable, ERC165 {\n using MinLibBytes for bytes;\n\n uint256 private constant MAX_RELAYS_RETURNED_COUNT = 1000;\n\n /// @notice Mapping from `RelayHub` address to a mapping from a Relay Manager address to its registration details.\n mapping(address => mapping(address => RelayInfo)) internal values;\n\n /// @notice Mapping from `RelayHub` address to an array of Relay Managers that are registered on that `RelayHub`.\n mapping(address => address[]) internal indexedValues;\n\n uint256 private immutable creationBlock;\n\n uint256 private relayRegistrationMaxAge;\n\n constructor(uint256 _relayRegistrationMaxAge) {\n setRelayRegistrationMaxAge(_relayRegistrationMaxAge);\n creationBlock = block.number;\n }\n\n /// @inheritdoc IRelayRegistrar\n function getCreationBlock() external override view returns (uint256){\n return creationBlock;\n }\n\n /// @inheritdoc IRelayRegistrar\n function getRelayRegistrationMaxAge() external override view returns (uint256){\n return relayRegistrationMaxAge;\n }\n\n /// @inheritdoc IRelayRegistrar\n function setRelayRegistrationMaxAge(uint256 _relayRegistrationMaxAge) public override onlyOwner {\n relayRegistrationMaxAge = _relayRegistrationMaxAge;\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n return interfaceId == type(IRelayRegistrar).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IRelayRegistrar\n function registerRelayServer(\n address relayHub,\n bytes32[3] calldata url\n ) external override {\n address relayManager = msg.sender;\n IRelayHub(relayHub).onRelayServerRegistered(relayManager);\n emit RelayServerRegistered(relayManager, relayHub, url);\n storeRelayServerRegistration(relayManager, relayHub, url);\n }\n\n function addItem(address relayHub, address relayManager) internal returns (RelayInfo storage) {\n RelayInfo storage storageInfo = values[relayHub][relayManager];\n if (storageInfo.lastSeenBlockNumber == 0) {\n indexedValues[relayHub].push(relayManager);\n }\n return storageInfo;\n }\n\n function storeRelayServerRegistration(\n address relayManager,\n address relayHub,\n bytes32[3] calldata url\n ) internal {\n RelayInfo storage storageInfo = addItem(relayHub, relayManager);\n if (storageInfo.firstSeenBlockNumber == 0) {\n storageInfo.firstSeenBlockNumber = uint32(block.number);\n storageInfo.firstSeenTimestamp = uint40(block.timestamp);\n }\n storageInfo.lastSeenBlockNumber = uint32(block.number);\n storageInfo.lastSeenTimestamp = uint40(block.timestamp);\n storageInfo.relayManager = relayManager;\n storageInfo.urlParts = url;\n }\n\n /// @inheritdoc IRelayRegistrar\n function getRelayInfo(address relayHub, address relayManager) public view override returns (RelayInfo memory) {\n RelayInfo memory info = values[relayHub][relayManager];\n require(info.lastSeenBlockNumber != 0, \"relayManager not found\");\n return info;\n }\n\n /// @inheritdoc IRelayRegistrar\n function readRelayInfos(\n address relayHub\n )\n public\n view\n override\n returns (\n RelayInfo[] memory info\n ) {\n uint256 blockTimestamp = block.timestamp;\n uint256 oldestBlockTimestamp = blockTimestamp >= relayRegistrationMaxAge ? blockTimestamp - relayRegistrationMaxAge : 0;\n return readRelayInfosInRange(relayHub, 0, oldestBlockTimestamp, MAX_RELAYS_RETURNED_COUNT);\n }\n\n /// @inheritdoc IRelayRegistrar\n function readRelayInfosInRange(\n address relayHub,\n uint256 oldestBlockNumber,\n uint256 oldestBlockTimestamp,\n uint256 maxCount\n )\n public\n view\n override\n returns (\n RelayInfo[] memory info\n ) {\n address[] storage items = indexedValues[relayHub];\n uint256 filled = 0;\n info = new RelayInfo[](items.length < maxCount ? items.length : maxCount);\n for (uint256 i = 0; i < items.length; i++) {\n address relayManager = items[i];\n RelayInfo memory relayInfo = getRelayInfo(relayHub, relayManager);\n if (\n relayInfo.lastSeenBlockNumber < oldestBlockNumber ||\n relayInfo.lastSeenTimestamp < oldestBlockTimestamp\n ) {\n continue;\n }\n // solhint-disable-next-line no-empty-blocks\n try IRelayHub(relayHub).verifyRelayManagerStaked(relayManager) {\n } catch (bytes memory /*lowLevelData*/) {\n continue;\n }\n info[filled++] = relayInfo;\n if (filled >= maxCount)\n break;\n }\n assembly { mstore(info, filled) }\n }\n}" + }, + "contracts-link/utils/RLPReader.sol": { + "content": "pragma solidity ^0.8.0;\n\n// SPDX-License-Identifier:APACHE-2.0\n/*\n* Taken from https://github.com/hamdiallam/Solidity-RLP\n*/\n/* solhint-disable */\n\nlibrary RLPReader {\n\n uint8 constant STRING_SHORT_START = 0x80;\n uint8 constant STRING_LONG_START = 0xb8;\n uint8 constant LIST_SHORT_START = 0xc0;\n uint8 constant LIST_LONG_START = 0xf8;\n uint8 constant WORD_SIZE = 32;\n\n struct RLPItem {\n uint len;\n uint memPtr;\n }\n\n using RLPReader for bytes;\n using RLPReader for uint;\n using RLPReader for RLPReader.RLPItem;\n\n // helper function to decode rlp encoded legacy ethereum transaction\n /*\n * @param rawTransaction RLP encoded legacy ethereum transaction rlp([nonce, gasPrice, gasLimit, to, value, data]))\n * @return tuple (nonce,gasLimit,to,value,data)\n */\n\n function decodeLegacyTransaction(bytes calldata rawTransaction) internal pure returns (uint, uint, address, uint, bytes memory){\n RLPReader.RLPItem[] memory values = rawTransaction.toRlpItem().toList(); // must convert to an rlpItem first!\n return (values[0].toUint(), values[2].toUint(), values[3].toAddress(), values[4].toUint(), values[5].toBytes());\n }\n\n /*\n * @param rawTransaction format: 0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, access_list]))\n * @return tuple (nonce,gasLimit,to,value,data)\n */\n function decodeTransactionType1(bytes calldata rawTransaction) internal pure returns (uint, uint, address, uint, bytes memory){\n bytes memory payload = rawTransaction[1:rawTransaction.length];\n RLPReader.RLPItem[] memory values = payload.toRlpItem().toList(); // must convert to an rlpItem first!\n return (values[1].toUint(), values[3].toUint(), values[4].toAddress(), values[5].toUint(), values[6].toBytes());\n }\n\n /*\n * @param rawTransaction format: 0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list]))\n * @return tuple (nonce,gasLimit,to,value,data)\n */\n function decodeTransactionType2(bytes calldata rawTransaction) internal pure returns (uint, uint, address, uint, bytes memory){\n bytes memory payload = rawTransaction[1:rawTransaction.length];\n RLPReader.RLPItem[] memory values = payload.toRlpItem().toList(); // must convert to an rlpItem first!\n return (values[1].toUint(), values[4].toUint(), values[5].toAddress(), values[6].toUint(), values[7].toBytes());\n }\n\n /*\n * @param item RLP encoded bytes\n */\n function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {\n if (item.length == 0)\n return RLPItem(0, 0);\n uint memPtr;\n assembly {\n memPtr := add(item, 0x20)\n }\n return RLPItem(item.length, memPtr);\n }\n /*\n * @param item RLP encoded list in bytes\n */\n function toList(RLPItem memory item) internal pure returns (RLPItem[] memory result) {\n require(isList(item), \"isList failed\");\n uint items = numItems(item);\n result = new RLPItem[](items);\n uint memPtr = item.memPtr + _payloadOffset(item.memPtr);\n uint dataLen;\n for (uint i = 0; i < items; i++) {\n dataLen = _itemLength(memPtr);\n result[i] = RLPItem(dataLen, memPtr);\n memPtr = memPtr + dataLen;\n }\n }\n /*\n * Helpers\n */\n // @return indicator whether encoded payload is a list. negate this function call for isData.\n function isList(RLPItem memory item) internal pure returns (bool) {\n uint8 byte0;\n uint memPtr = item.memPtr;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n if (byte0 < LIST_SHORT_START)\n return false;\n return true;\n }\n // @return number of payload items inside an encoded list.\n function numItems(RLPItem memory item) internal pure returns (uint) {\n uint count = 0;\n uint currPtr = item.memPtr + _payloadOffset(item.memPtr);\n uint endPtr = item.memPtr + item.len;\n while (currPtr < endPtr) {\n currPtr = currPtr + _itemLength(currPtr);\n // skip over an item\n count++;\n }\n return count;\n }\n // @return entire rlp item byte length\n function _itemLength(uint memPtr) internal pure returns (uint len) {\n uint byte0;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n if (byte0 < STRING_SHORT_START)\n return 1;\n else if (byte0 < STRING_LONG_START)\n return byte0 - STRING_SHORT_START + 1;\n else if (byte0 < LIST_SHORT_START) {\n assembly {\n let byteLen := sub(byte0, 0xb7) // number of bytes the actual length is\n memPtr := add(memPtr, 1) // skip over the first byte\n /* 32 byte word size */\n let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len\n len := add(dataLen, add(byteLen, 1))\n }\n }\n else if (byte0 < LIST_LONG_START) {\n return byte0 - LIST_SHORT_START + 1;\n }\n else {\n assembly {\n let byteLen := sub(byte0, 0xf7)\n memPtr := add(memPtr, 1)\n let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length\n len := add(dataLen, add(byteLen, 1))\n }\n }\n }\n // @return number of bytes until the data\n function _payloadOffset(uint memPtr) internal pure returns (uint) {\n uint byte0;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n if (byte0 < STRING_SHORT_START)\n return 0;\n else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START))\n return 1;\n else if (byte0 < LIST_SHORT_START) // being explicit\n return byte0 - (STRING_LONG_START - 1) + 1;\n else\n return byte0 - (LIST_LONG_START - 1) + 1;\n }\n /** RLPItem conversions into data types **/\n // @returns raw rlp encoding in bytes\n function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {\n bytes memory result = new bytes(item.len);\n uint ptr;\n assembly {\n ptr := add(0x20, result)\n }\n copy(item.memPtr, ptr, item.len);\n return result;\n }\n\n function toBoolean(RLPItem memory item) internal pure returns (bool) {\n require(item.len == 1, \"Invalid RLPItem. Booleans are encoded in 1 byte\");\n uint result;\n uint memPtr = item.memPtr;\n assembly {\n result := byte(0, mload(memPtr))\n }\n return result == 0 ? false : true;\n }\n\n function toAddress(RLPItem memory item) internal pure returns (address) {\n // 1 byte for the length prefix according to RLP spec\n require(item.len <= 21, \"Invalid RLPItem. Addresses are encoded in 20 bytes or less\");\n return address(uint160(toUint(item)));\n }\n\n function toUint(RLPItem memory item) internal pure returns (uint) {\n uint offset = _payloadOffset(item.memPtr);\n uint len = item.len - offset;\n uint memPtr = item.memPtr + offset;\n uint result;\n assembly {\n result := div(mload(memPtr), exp(256, sub(32, len))) // shift to the correct location\n }\n return result;\n }\n\n function toBytes(RLPItem memory item) internal pure returns (bytes memory) {\n uint offset = _payloadOffset(item.memPtr);\n uint len = item.len - offset;\n // data length\n bytes memory result = new bytes(len);\n uint destPtr;\n assembly {\n destPtr := add(0x20, result)\n }\n copy(item.memPtr + offset, destPtr, len);\n return result;\n }\n /*\n * @param src Pointer to source\n * @param dest Pointer to destination\n * @param len Amount of memory to copy from the source\n */\n function copy(uint src, uint dest, uint len) internal pure {\n if (len == 0) return;\n\n // copy as many word sizes as possible\n for (; len >= WORD_SIZE; len -= WORD_SIZE) {\n assembly {\n mstore(dest, mload(src))\n }\n\n src += WORD_SIZE;\n dest += WORD_SIZE;\n }\n\n if (len > 0) {\n // left over bytes. Mask is used to remove unwanted bytes from the word\n uint mask = 256 ** (WORD_SIZE - len) - 1;\n assembly {\n let srcpart := and(mload(src), not(mask)) // zero out src\n let destpart := and(mload(dest), mask) // retrieve the bytes\n mstore(dest, or(destpart, srcpart))\n }\n }\n }\n}" + }, + "hardhat/console.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nlibrary console {\n address constant CONSOLE_ADDRESS =\n 0x000000000000000000636F6e736F6c652e6c6f67;\n\n function _sendLogPayloadImplementation(bytes memory payload) internal view {\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n pop(\n staticcall(\n gas(),\n consoleAddress,\n add(payload, 32),\n mload(payload),\n 0,\n 0\n )\n )\n }\n }\n\n function _castToPure(\n function(bytes memory) internal view fnIn\n ) internal pure returns (function(bytes memory) pure fnOut) {\n assembly {\n fnOut := fnIn\n }\n }\n\n function _sendLogPayload(bytes memory payload) internal pure {\n _castToPure(_sendLogPayloadImplementation)(payload);\n }\n\n function log() internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n function logInt(int256 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function logUint(uint256 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function logString(string memory p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint256 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function log(string memory p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint256 p0, uint256 p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n }\n\n function log(uint256 p0, string memory p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n }\n\n function log(uint256 p0, bool p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n }\n\n function log(uint256 p0, address p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n }\n\n function log(string memory p0, uint256 p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint256 p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint256 p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file