diff --git a/contracts/deployments/sepolia/WiseAccountRegistrationProcessor.json b/contracts/deployments/sepolia/WiseAccountRegistrationProcessor.json index e6e32170e..faf054316 100644 --- a/contracts/deployments/sepolia/WiseAccountRegistrationProcessor.json +++ b/contracts/deployments/sepolia/WiseAccountRegistrationProcessor.json @@ -1,5 +1,5 @@ { - "address": "0x8E9ca43089F380A904D2d121fAa021bb4fbb0f4a", + "address": "0x907D379E034f45688Fe895FCCf7ee0947D3C2Ec4", "abi": [ { "inputs": [ @@ -146,6 +146,11 @@ "internalType": "string", "name": "wiseTagHash", "type": "string" + }, + { + "internalType": "address", + "name": "userAddress", + "type": "address" } ], "internalType": "struct IWiseAccountRegistrationProcessor.RegistrationData", @@ -163,7 +168,7 @@ "type": "tuple" } ], - "name": "processAccountProof", + "name": "processProof", "outputs": [ { "internalType": "bytes32", @@ -287,6 +292,11 @@ "internalType": "string", "name": "wiseTagHash", "type": "string" + }, + { + "internalType": "address", + "name": "userAddress", + "type": "address" } ], "internalType": "struct IWiseAccountRegistrationProcessor.RegistrationData", @@ -311,39 +321,39 @@ "type": "function" } ], - "transactionHash": "0x1f117b3bd666935a7962bc829dd2599c4a336b3dbcd77b45d3765d42c3a5708c", + "transactionHash": "0xc9eab535429a563b9c2144b97bae1e8a5afd10a09aa473f4dc90aa065456f968", "receipt": { "to": null, "from": "0x4e39cF8578698131c57404e8bc3eEC820EDa51d8", - "contractAddress": "0x8E9ca43089F380A904D2d121fAa021bb4fbb0f4a", - "transactionIndex": 25, - "gasUsed": "1436146", - "logsBloom": "0x00000000000000000100000000000000000000000000000000800000000000040000000000000000000000100000000000000000000000000000000000002000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000100000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xbb7975cf76b1d5d98e4082718bcf569e7d5fe8a9d5ebe5721446b54244a024b2", - "transactionHash": "0x1f117b3bd666935a7962bc829dd2599c4a336b3dbcd77b45d3765d42c3a5708c", + "contractAddress": "0x907D379E034f45688Fe895FCCf7ee0947D3C2Ec4", + "transactionIndex": 30, + "gasUsed": "1449760", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000040000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000008000000000000000020000000000000000000000000000000000000000000000000000000000000000000000020000000000100000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x3449048e150b8a46fd5f3fed7843d48cb81da579e5e3f6b242c049b9b7f1b3a6", + "transactionHash": "0xc9eab535429a563b9c2144b97bae1e8a5afd10a09aa473f4dc90aa065456f968", "logs": [ { - "transactionIndex": 25, - "blockNumber": 5574196, - "transactionHash": "0x1f117b3bd666935a7962bc829dd2599c4a336b3dbcd77b45d3765d42c3a5708c", - "address": "0x8E9ca43089F380A904D2d121fAa021bb4fbb0f4a", + "transactionIndex": 30, + "blockNumber": 5635194, + "transactionHash": "0xc9eab535429a563b9c2144b97bae1e8a5afd10a09aa473f4dc90aa065456f968", + "address": "0x907D379E034f45688Fe895FCCf7ee0947D3C2Ec4", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000004e39cf8578698131c57404e8bc3eec820eda51d8" ], "data": "0x", - "logIndex": 17, - "blockHash": "0xbb7975cf76b1d5d98e4082718bcf569e7d5fe8a9d5ebe5721446b54244a024b2" + "logIndex": 44, + "blockHash": "0x3449048e150b8a46fd5f3fed7843d48cb81da579e5e3f6b242c049b9b7f1b3a6" } ], - "blockNumber": 5574196, - "cumulativeGasUsed": "2605796", + "blockNumber": 5635194, + "cumulativeGasUsed": "8653748", "status": 1, "byzantium": true }, "args": [ - "0x7eDD66B19A22293af86A2d96761FD7146BA3fF6c", + "0xF44B36992B96043128A3240744Bfe9b070a098Fa", "0x166338393593e85bfde8B65358Ec5801A3445D12", "0xAf0196f22a1383B779E3f833AD35BFf38722c8AD", "0", @@ -351,10 +361,10 @@ "wise.com" ], "numDeployments": 1, - "solcInputHash": "6e4c0155cf194d54974389502ced73c2", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_ramp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"},{\"internalType\":\"contract INullifierRegistry\",\"name\":\"_nullifierRegistry\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_host\",\"type\":\"string\"}],\"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\":false,\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"}],\"name\":\"VerifierSigningKeySet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"endpoint\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"host\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nullifierRegistry\",\"outputs\":[{\"internalType\":\"contract INullifierRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"profileId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"wiseTagHash\",\"type\":\"string\"}],\"internalType\":\"struct IWiseAccountRegistrationProcessor.RegistrationData\",\"name\":\"public_values\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"internalType\":\"struct IWiseAccountRegistrationProcessor.RegistrationProof\",\"name\":\"_proof\",\"type\":\"tuple\"}],\"name\":\"processAccountProof\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"onRampId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"wiseTagHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ramp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"}],\"name\":\"setTimestampBuffer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"}],\"name\":\"setVerifierSigningKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timestampBuffer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verifierSigningKey\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"profileId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"wiseTagHash\",\"type\":\"string\"}],\"internalType\":\"struct IWiseAccountRegistrationProcessor.RegistrationData\",\"name\":\"_publicValues\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"_proof\",\"type\":\"bytes\"}],\"name\":\"verifyProof\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setTimestampBuffer(uint256)\":{\"params\":{\"_timestampBuffer\":\"The timestamp buffer for validated TLS calls\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"setTimestampBuffer(uint256)\":{\"notice\":\"ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2 timestamps.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ramps/wise/WiseAccountRegistrationProcessor.sol\":\"WiseAccountRegistrationProcessor\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"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/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/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"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\"},\"contracts/lib/StringConversionUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\n// Building on zk-email's StringUtils library we add the ability to handle decimals when\\n// converting from string to Uint\\nlibrary StringConversionUtils {\\n \\n /**\\n * @notice Function that parses numbers returned as strings including floating point numbers. Returned floating point\\n * numbers are to have the desired amount of decimal specified. If the stringified version of the floating point\\n * number has more decimal places than desired then the function will revert in order to be maximally safe. If\\n * the returned number has multiple floating points then the function will revert.\\n *\\n * Examples: _s = \\\"12.34\\\", _expectedDecimals = 6 => 12340000\\n * _s = \\\"12.34\\\", _expectedDecimals = 2 => 1234\\n * _s = \\\"12.34\\\", _expectedDecimals = 1 => REVERT (we never want loss of precision only addition)\\n * _s = \\\"12.34.56\\\", _expectedDecimals = 6 => REVERT (Invalid number)\\n *\\n * @param _s String being processed\\n * @param _desiredDecimals Desired amount of decimal places\\n */\\n function stringToUint(string memory _s, uint256 _desiredDecimals) internal pure returns (uint256) {\\n return stringToUint(_s, 0x2E, _desiredDecimals);\\n }\\n\\n function stringToUint(\\n string memory _s,\\n bytes1 _decimalCharacter,\\n uint256 _desiredDecimals\\n )\\n internal\\n pure\\n returns (uint256)\\n {\\n bytes memory b = bytes(_s);\\n\\n uint256 result = 0;\\n uint256 decimalPlaces = 0;\\n\\n bool decimals = false;\\n for (uint256 i = 0; i < b.length; i++) {\\n if (b[i] >= 0x30 && b[i] <= 0x39) {\\n result = result * 10 + (uint256(uint8(b[i])) - 48);\\n }\\n\\n if (decimals) {\\n decimalPlaces++;\\n }\\n\\n if (b[i] == _decimalCharacter) {\\n require(decimals == false, \\\"String has multiple decimals\\\");\\n decimals = true;\\n }\\n }\\n\\n require(decimalPlaces <= _desiredDecimals, \\\"String has too many decimal places\\\");\\n return result * (10 ** (_desiredDecimals - decimalPlaces));\\n }\\n\\n /**\\n * @notice Function that returns a substring from _startIndex to _endIndex (non-inclusive).\\n *\\n * @param _str String being processed\\n * @param _startIndex Index to start parsing from\\n * @param _endIndex Index to stop parsing at (index not included in result)\\n */\\n function substring(string memory _str, uint _startIndex, uint _endIndex) internal pure returns (string memory ) {\\n bytes memory strBytes = bytes(_str);\\n bytes memory result = new bytes(_endIndex-_startIndex);\\n for(uint i = _startIndex; i < _endIndex; i++) {\\n result[i-_startIndex] = strBytes[i];\\n }\\n return string(result);\\n }\\n\\n function replaceString(\\n string memory _str,\\n string memory _lookupValue,\\n string memory _replaceValue\\n )\\n internal\\n pure\\n returns (string memory)\\n {\\n bytes memory strBytes = bytes(_str);\\n bytes memory lookupBytes = bytes(_lookupValue);\\n\\n uint256 lookupIndex = indexOf(_str, _lookupValue);\\n if (lookupIndex == type(uint256).max) {\\n return _str;\\n }\\n\\n // Split the original string into two parts: before and after the keyword\\n string memory beforeKeyword = substring(_str, 0, lookupIndex);\\n string memory afterKeyword = substring(_str, lookupIndex + lookupBytes.length, strBytes.length);\\n \\n return string.concat(beforeKeyword, _replaceValue, afterKeyword);\\n }\\n\\n function indexOf(string memory str, string memory substr) internal pure returns (uint) {\\n bytes memory strBytes = bytes(str);\\n bytes memory substrBytes = bytes(substr);\\n \\n if (strBytes.length < substrBytes.length) return type(uint256).max;\\n \\n for (uint i = 0; i <= strBytes.length - substrBytes.length; i++) {\\n bool found = true;\\n for (uint j = 0; j < substrBytes.length; j++) {\\n if (strBytes[i + j] != substrBytes[j]) {\\n found = false;\\n break;\\n }\\n }\\n if (found) return i;\\n }\\n \\n return type(uint256).max;\\n }\\n\\n function stringComparison(string memory _a, string memory _b) internal pure returns (bool) {\\n return (keccak256(abi.encodePacked(_a)) == keccak256(abi.encodePacked(_b)));\\n }\\n}\\n\",\"keccak256\":\"0xfcdfb3c2c8d5a6b7f480f827049782a70fb98f8b3838dcad0e0bb95237b94a0c\",\"license\":\"MIT\"},\"contracts/processors/TLSBaseProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { ECDSA } from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { SignatureChecker } from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\n\\nimport { INullifierRegistry } from \\\"./nullifierRegistries/INullifierRegistry.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract TLSBaseProcessor is Ownable {\\n\\n using SignatureChecker for address;\\n using ECDSA for bytes32;\\n\\n /* ============ Modifiers ============ */\\n modifier onlyRamp() {\\n require(msg.sender == ramp, \\\"Only Ramp can call this function\\\");\\n _;\\n }\\n\\n /* ============ State Variables ============ */\\n address public immutable ramp;\\n string public endpoint;\\n string public host;\\n\\n INullifierRegistry public nullifierRegistry;\\n uint256 public timestampBuffer;\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _ramp,\\n INullifierRegistry _nullifierRegistry,\\n uint256 _timestampBuffer,\\n string memory _endpoint,\\n string memory _host\\n )\\n Ownable()\\n {\\n ramp = _ramp;\\n endpoint = _endpoint;\\n host = _host;\\n\\n nullifierRegistry = _nullifierRegistry;\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ External Functions ============ */\\n\\n /**\\n * @notice ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds\\n * that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2\\n * timestamps.\\n *\\n * @param _timestampBuffer The timestamp buffer for validated TLS calls\\n */\\n function setTimestampBuffer(uint256 _timestampBuffer) external onlyOwner {\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ Internal Functions ============ */\\n\\n function _validateTLSEndpoint(\\n string memory _expectedEndpoint,\\n string memory _passedEndpoint\\n )\\n internal\\n pure\\n {\\n require(\\n keccak256(abi.encode(_expectedEndpoint)) == keccak256(abi.encode(_passedEndpoint)),\\n \\\"Endpoint does not match expected\\\"\\n );\\n }\\n\\n function _validateTLSHost(\\n string memory _expectedHost,\\n string memory _passedHost\\n )\\n internal\\n pure\\n {\\n require(\\n keccak256(abi.encode(_expectedHost)) == keccak256(abi.encode(_passedHost)),\\n \\\"Host does not match expected\\\"\\n );\\n }\\n\\n function _validateAndAddNullifier(bytes32 _nullifier) internal {\\n require(!nullifierRegistry.isNullified(_nullifier), \\\"Nullifier has already been used\\\");\\n nullifierRegistry.addNullifier(_nullifier);\\n }\\n\\n function _isValidVerifierSignature(\\n bytes memory _message,\\n bytes memory _signature,\\n address _verifier\\n )\\n internal\\n view\\n returns(bool)\\n {\\n bytes32 verifierPayload = keccak256(_message).toEthSignedMessageHash();\\n\\n return _verifier.isValidSignatureNow(verifierPayload, _signature);\\n }\\n}\\n\",\"keccak256\":\"0xbbdb8f203288645916ad04ee65625fae570ed091fbf243a706df7991b29ffe61\",\"license\":\"MIT\"},\"contracts/processors/nullifierRegistries/INullifierRegistry.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface INullifierRegistry {\\n function addNullifier(bytes32 _nullifier) external;\\n function isNullified(bytes32 _nullifier) external view returns(bool);\\n}\\n\",\"keccak256\":\"0x107164bc9a320938b513305878163b7fa884da4cdae58d0c8e81bfbb00c97c5e\",\"license\":\"MIT\"},\"contracts/ramps/wise/WiseAccountRegistrationProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { ECDSA } from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport { SignatureChecker } from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\n\\nimport { INullifierRegistry } from \\\"../../processors/nullifierRegistries/INullifierRegistry.sol\\\";\\nimport { IWiseAccountRegistrationProcessor } from \\\"./interfaces/IWiseAccountRegistrationProcessor.sol\\\";\\nimport { StringConversionUtils } from \\\"../../lib/StringConversionUtils.sol\\\";\\nimport { TLSBaseProcessor } from \\\"../../processors/TLSBaseProcessor.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract WiseAccountRegistrationProcessor is IWiseAccountRegistrationProcessor, TLSBaseProcessor {\\n\\n using ECDSA for bytes32;\\n using SignatureChecker for address;\\n using StringConversionUtils for string;\\n \\n /* ============ Events ============ */\\n event VerifierSigningKeySet(address _verifierSigningKey);\\n \\n /* ============ Public Variables ============ */\\n address public verifierSigningKey;\\n \\n /* ============ Constructor ============ */\\n constructor(\\n address _ramp,\\n address _verifierSigningKey,\\n INullifierRegistry _nullifierRegistry,\\n uint256 _timestampBuffer,\\n string memory _endpoint,\\n string memory _host\\n )\\n TLSBaseProcessor(\\n _ramp,\\n _nullifierRegistry,\\n _timestampBuffer,\\n _endpoint,\\n _host\\n )\\n {\\n verifierSigningKey = _verifierSigningKey;\\n }\\n\\n /* ============ External Functions ============ */\\n\\n function processAccountProof(\\n IWiseAccountRegistrationProcessor.RegistrationProof calldata _proof\\n )\\n public\\n override\\n onlyRamp\\n returns(bytes32 onRampId, bytes32 wiseTagHash)\\n {\\n _validateProof(_proof.public_values, _proof.proof);\\n\\n _validateTLSEndpoint(endpoint, _proof.public_values.endpoint);\\n _validateTLSHost(host, _proof.public_values.host);\\n\\n _validateAndAddNullifier(keccak256(abi.encode(\\\"registration\\\", _proof.public_values.profileId)));\\n\\n onRampId = bytes32(_proof.public_values.profileId.stringToUint(0));\\n wiseTagHash = bytes32(_proof.public_values.wiseTagHash.stringToUint(0));\\n }\\n\\n /* ============ External Admin Functions ============ */\\n\\n function setVerifierSigningKey(address _verifierSigningKey) external onlyOwner {\\n verifierSigningKey = _verifierSigningKey;\\n\\n emit VerifierSigningKeySet(_verifierSigningKey);\\n }\\n\\n /* ============ View Functions ============ */\\n\\n function verifyProof(\\n IWiseAccountRegistrationProcessor.RegistrationData memory _publicValues,\\n bytes memory _proof\\n )\\n public\\n view\\n returns(bool)\\n {\\n bytes memory encodedMessage = abi.encode(_publicValues.endpoint, _publicValues.host, _publicValues.profileId, _publicValues.wiseTagHash);\\n return _isValidVerifierSignature(encodedMessage, _proof, verifierSigningKey);\\n }\\n \\n /* ============ Internal Functions ============ */\\n\\n function _validateProof(\\n IWiseAccountRegistrationProcessor.RegistrationData memory _publicValues, \\n bytes memory _proof\\n )\\n internal\\n view\\n { \\n require(\\n verifyProof(_publicValues, _proof),\\n \\\"Invalid signature from verifier\\\"\\n );\\n }\\n}\\n\",\"keccak256\":\"0xa5e25364b5fb6a32d453245b235ac66f9b93363b2b9cebdf4b465cea35962742\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseAccountRegistrationProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseAccountRegistrationProcessor {\\n\\n struct RegistrationData {\\n string endpoint;\\n string host;\\n string profileId;\\n string wiseTagHash;\\n }\\n\\n struct RegistrationProof {\\n RegistrationData public_values;\\n bytes proof;\\n }\\n\\n function processAccountProof(\\n RegistrationProof calldata _proof\\n )\\n external\\n returns (bytes32, bytes32);\\n}\\n\",\"keccak256\":\"0x99082f42d3232cf43f2799492721369f11636b8be18cb4486f037dca2e894584\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523480156200001157600080fd5b50604051620019db380380620019db8339810160408190526200003491620001e2565b85848484846200004433620000b4565b6001600160a01b03851660805260016200005f838262000324565b5060026200006e828262000324565b5050600380546001600160a01b039485166001600160a01b03199182161790915560049290925550600580549890921697169690961790955550620003f0945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200011a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200014557600080fd5b81516001600160401b03808211156200016257620001626200011d565b604051601f8301601f19908116603f011681019082821181831017156200018d576200018d6200011d565b81604052838152602092508683858801011115620001aa57600080fd5b600091505b83821015620001ce5785820183015181830184015290820190620001af565b600093810190920192909252949350505050565b60008060008060008060c08789031215620001fc57600080fd5b8651620002098162000104565b60208801519096506200021c8162000104565b60408801519095506200022f8162000104565b6060880151608089015191955093506001600160401b03808211156200025457600080fd5b620002628a838b0162000133565b935060a08901519150808211156200027957600080fd5b506200028889828a0162000133565b9150509295509295509295565b600181811c90821680620002aa57607f821691505b602082108103620002cb57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200031f57600081815260208120601f850160051c81016020861015620002fa5750805b601f850160051c820191505b818110156200031b5782815560010162000306565b5050505b505050565b81516001600160401b038111156200034057620003406200011d565b620003588162000351845462000295565b84620002d1565b602080601f831160018114620003905760008415620003775750858301515b600019600386901b1c1916600185901b1785556200031b565b600085815260208120601f198616915b82811015620003c157888601518255948401946001909101908401620003a0565b5085821015620003e05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516115c86200041360003960008181610109015261031d01526115c86000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c80638da5cb5b1161008c578063b870676c11610066578063b870676c146101cc578063dbac5821146101df578063f2fde38b146101f6578063f437bc591461020957600080fd5b80638da5cb5b14610185578063b06b02b214610196578063b2a3fda4146101b957600080fd5b80630fa4ed4d146100d457806315d276e1146101045780634e06a32b1461012b5780635e280f1114610140578063715018a61461015557806375848b321461015d575b600080fd5b6005546100e7906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100e77f000000000000000000000000000000000000000000000000000000000000000081565b61013e610139366004610f5f565b610211565b005b61014861026d565b6040516100fb9190610fd8565b61013e6102fb565b61017061016b366004610feb565b61030f565b604080519283526020830191909152016100fb565b6000546001600160a01b03166100e7565b6101a96101a43660046111b4565b610678565b60405190151581526020016100fb565b61013e6101c736600461122c565b6106d8565b6003546100e7906001600160a01b031681565b6101e860045481565b6040519081526020016100fb565b61013e610204366004610f5f565b6106e5565b61014861075e565b61021961076b565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fb8603ceabf8ee4633f1fd8c0ae9e0e64f2fc2fea5cb79a96c18efd007aab6f969060200160405180910390a150565b6001805461027a90611245565b80601f01602080910402602001604051908101604052809291908181526020018280546102a690611245565b80156102f35780601f106102c8576101008083540402835291602001916102f3565b820191906000526020600020905b8154815290600101906020018083116102d657829003601f168201915b505050505081565b61030361076b565b61030d60006107c5565b565b600080336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461038f5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792052616d702063616e2063616c6c20746869732066756e6374696f6e60448201526064015b60405180910390fd5b6103ec61039c848061127f565b6103a59061129f565b6103b260208601866112ab565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061081592505050565b6104cc600180546103fc90611245565b80601f016020809104026020016040519081016040528092919081815260200182805461042890611245565b80156104755780601f1061044a57610100808354040283529160200191610475565b820191906000526020600020905b81548152906001019060200180831161045857829003601f168201915b50610488935088925082915061127f9050565b61049290806112ab565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061086f92505050565b6105b0600280546104dc90611245565b80601f016020809104026020016040519081016040528092919081815260200182805461050890611245565b80156105555780601f1061052a57610100808354040283529160200191610555565b820191906000526020600020905b81548152906001019060200180831161053857829003601f168201915b50610568935088925082915061127f9050565b6105769060208101906112ab565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061090a92505050565b6105f76105bd848061127f565b6105cb9060408101906112ab565b6040516020016105dc9291906112f2565b604051602081830303815290604052805190602001206109a5565b6106516000610606858061127f565b6106149060408101906112ab565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293925050610ac09050565b91506106706000610662858061127f565b6106149060608101906112ab565b919391925050565b60008083600001518460200151856040015186606001516040516020016106a29493929190611344565b60408051601f198184030181529190526005549091506106ce90829085906001600160a01b0316610ad8565b9150505b92915050565b6106e061076b565b600455565b6106ed61076b565b6001600160a01b0381166107525760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610386565b61075b816107c5565b50565b6002805461027a90611245565b6000546001600160a01b0316331461030d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610386565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61081f8282610678565b61086b5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e61747572652066726f6d207665726966696572006044820152606401610386565b5050565b806040516020016108809190610fd8565b60405160208183030381529060405280519060200120826040516020016108a79190610fd8565b604051602081830303815290604052805190602001201461086b5760405162461bcd60e51b815260206004820181905260248201527f456e64706f696e7420646f6573206e6f74206d617463682065787065637465646044820152606401610386565b8060405160200161091b9190610fd8565b60405160208183030381529060405280519060200120826040516020016109429190610fd8565b604051602081830303815290604052805190602001201461086b5760405162461bcd60e51b815260206004820152601c60248201527f486f737420646f6573206e6f74206d61746368206578706563746564000000006044820152606401610386565b60035460405163169394bb60e01b8152600481018390526001600160a01b039091169063169394bb90602401602060405180830381865afa1580156109ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a12919061139c565b15610a5f5760405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e2075736564006044820152606401610386565b600354604051632dea6f9960e11b8152600481018390526001600160a01b0390911690635bd4df3290602401600060405180830381600087803b158015610aa557600080fd5b505af1158015610ab9573d6000803e3d6000fd5b5050505050565b6000610ad183601760f91b84610b2c565b9392505050565b825160208401207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c8120610b236001600160a01b0384168286610d09565b95945050505050565b600083818080805b8451811015610c8257603060f81b858281518110610b5457610b546113be565b01602001516001600160f81b03191610801590610b955750603960f81b858281518110610b8357610b836113be565b01602001516001600160f81b03191611155b15610bd8576030858281518110610bae57610bae6113be565b0160200151610bc0919060f81c6113ea565b610bcb85600a6113fd565b610bd59190611414565b93505b8115610bec5782610be881611427565b9350505b876001600160f81b031916858281518110610c0957610c096113be565b01602001516001600160f81b03191603610c70578115610c6b5760405162461bcd60e51b815260206004820152601c60248201527f537472696e6720686173206d756c7469706c6520646563696d616c73000000006044820152606401610386565b600191505b80610c7a81611427565b915050610b34565b5085821115610cde5760405162461bcd60e51b815260206004820152602260248201527f537472696e672068617320746f6f206d616e7920646563696d616c20706c6163604482015261657360f01b6064820152608401610386565b610ce882876113ea565b610cf390600a611524565b610cfd90846113fd565b98975050505050505050565b6000806000610d188585610d6a565b90925090506000816004811115610d3157610d31611530565b148015610d4f5750856001600160a01b0316826001600160a01b0316145b80610d605750610d60868686610daf565b9695505050505050565b6000808251604103610da05760208301516040840151606085015160001a610d9487828585610e9b565b94509450505050610da8565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b8686604051602401610dd9929190611546565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610e179190611567565b600060405180830381855afa9150503d8060008114610e52576040519150601f19603f3d011682016040523d82523d6000602084013e610e57565b606091505b5091509150818015610e6b57506020815110155b8015610d6057508051630b135d3f60e11b90610e909083016020908101908401611579565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610ed25750600090506003610f56565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610f26573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610f4f57600060019250925050610f56565b9150600090505b94509492505050565b600060208284031215610f7157600080fd5b81356001600160a01b0381168114610ad157600080fd5b60005b83811015610fa3578181015183820152602001610f8b565b50506000910152565b60008151808452610fc4816020860160208601610f88565b601f01601f19169290920160200192915050565b602081526000610ad16020830184610fac565b600060208284031215610ffd57600080fd5b813567ffffffffffffffff81111561101457600080fd5b820160408185031215610ad157600080fd5b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561105f5761105f611026565b60405290565b600067ffffffffffffffff8084111561108057611080611026565b604051601f8501601f19908116603f011681019082821181831017156110a8576110a8611026565b816040528093508581528686860111156110c157600080fd5b858560208301376000602087830101525050509392505050565b600082601f8301126110ec57600080fd5b610ad183833560208501611065565b60006080828403121561110d57600080fd5b61111561103c565b9050813567ffffffffffffffff8082111561112f57600080fd5b61113b858386016110db565b8352602084013591508082111561115157600080fd5b61115d858386016110db565b6020840152604084013591508082111561117657600080fd5b611182858386016110db565b6040840152606084013591508082111561119b57600080fd5b506111a8848285016110db565b60608301525092915050565b600080604083850312156111c757600080fd5b823567ffffffffffffffff808211156111df57600080fd5b6111eb868387016110fb565b9350602085013591508082111561120157600080fd5b508301601f8101851361121357600080fd5b61122285823560208401611065565b9150509250929050565b60006020828403121561123e57600080fd5b5035919050565b600181811c9082168061125957607f821691505b60208210810361127957634e487b7160e01b600052602260045260246000fd5b50919050565b60008235607e1983360301811261129557600080fd5b9190910192915050565b60006106d236836110fb565b6000808335601e198436030181126112c257600080fd5b83018035915067ffffffffffffffff8211156112dd57600080fd5b602001915036819003821315610da857600080fd5b60408152600c60408201526b3932b3b4b9ba3930ba34b7b760a11b606082015260806020820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101919050565b6080815260006113576080830187610fac565b82810360208401526113698187610fac565b9050828103604084015261137d8186610fac565b905082810360608401526113918185610fac565b979650505050505050565b6000602082840312156113ae57600080fd5b81518015158114610ad157600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b818103818111156106d2576106d26113d4565b80820281158282048414176106d2576106d26113d4565b808201808211156106d2576106d26113d4565b600060018201611439576114396113d4565b5060010190565b600181815b8085111561147b578160001904821115611461576114616113d4565b8085161561146e57918102915b93841c9390800290611445565b509250929050565b600082611492575060016106d2565b8161149f575060006106d2565b81600181146114b557600281146114bf576114db565b60019150506106d2565b60ff8411156114d0576114d06113d4565b50506001821b6106d2565b5060208310610133831016604e8410600b84101617156114fe575081810a6106d2565b6115088383611440565b806000190482111561151c5761151c6113d4565b029392505050565b6000610ad18383611483565b634e487b7160e01b600052602160045260246000fd5b82815260406020820152600061155f6040830184610fac565b949350505050565b60008251611295818460208701610f88565b60006020828403121561158b57600080fd5b505191905056fea26469706673582212203e98302b127b19eb5c2f90167d93f78ee198dd9265bb36ff80173ab3384c571164736f6c63430008120033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c80638da5cb5b1161008c578063b870676c11610066578063b870676c146101cc578063dbac5821146101df578063f2fde38b146101f6578063f437bc591461020957600080fd5b80638da5cb5b14610185578063b06b02b214610196578063b2a3fda4146101b957600080fd5b80630fa4ed4d146100d457806315d276e1146101045780634e06a32b1461012b5780635e280f1114610140578063715018a61461015557806375848b321461015d575b600080fd5b6005546100e7906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100e77f000000000000000000000000000000000000000000000000000000000000000081565b61013e610139366004610f5f565b610211565b005b61014861026d565b6040516100fb9190610fd8565b61013e6102fb565b61017061016b366004610feb565b61030f565b604080519283526020830191909152016100fb565b6000546001600160a01b03166100e7565b6101a96101a43660046111b4565b610678565b60405190151581526020016100fb565b61013e6101c736600461122c565b6106d8565b6003546100e7906001600160a01b031681565b6101e860045481565b6040519081526020016100fb565b61013e610204366004610f5f565b6106e5565b61014861075e565b61021961076b565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fb8603ceabf8ee4633f1fd8c0ae9e0e64f2fc2fea5cb79a96c18efd007aab6f969060200160405180910390a150565b6001805461027a90611245565b80601f01602080910402602001604051908101604052809291908181526020018280546102a690611245565b80156102f35780601f106102c8576101008083540402835291602001916102f3565b820191906000526020600020905b8154815290600101906020018083116102d657829003601f168201915b505050505081565b61030361076b565b61030d60006107c5565b565b600080336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461038f5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792052616d702063616e2063616c6c20746869732066756e6374696f6e60448201526064015b60405180910390fd5b6103ec61039c848061127f565b6103a59061129f565b6103b260208601866112ab565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061081592505050565b6104cc600180546103fc90611245565b80601f016020809104026020016040519081016040528092919081815260200182805461042890611245565b80156104755780601f1061044a57610100808354040283529160200191610475565b820191906000526020600020905b81548152906001019060200180831161045857829003601f168201915b50610488935088925082915061127f9050565b61049290806112ab565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061086f92505050565b6105b0600280546104dc90611245565b80601f016020809104026020016040519081016040528092919081815260200182805461050890611245565b80156105555780601f1061052a57610100808354040283529160200191610555565b820191906000526020600020905b81548152906001019060200180831161053857829003601f168201915b50610568935088925082915061127f9050565b6105769060208101906112ab565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061090a92505050565b6105f76105bd848061127f565b6105cb9060408101906112ab565b6040516020016105dc9291906112f2565b604051602081830303815290604052805190602001206109a5565b6106516000610606858061127f565b6106149060408101906112ab565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293925050610ac09050565b91506106706000610662858061127f565b6106149060608101906112ab565b919391925050565b60008083600001518460200151856040015186606001516040516020016106a29493929190611344565b60408051601f198184030181529190526005549091506106ce90829085906001600160a01b0316610ad8565b9150505b92915050565b6106e061076b565b600455565b6106ed61076b565b6001600160a01b0381166107525760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610386565b61075b816107c5565b50565b6002805461027a90611245565b6000546001600160a01b0316331461030d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610386565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61081f8282610678565b61086b5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e61747572652066726f6d207665726966696572006044820152606401610386565b5050565b806040516020016108809190610fd8565b60405160208183030381529060405280519060200120826040516020016108a79190610fd8565b604051602081830303815290604052805190602001201461086b5760405162461bcd60e51b815260206004820181905260248201527f456e64706f696e7420646f6573206e6f74206d617463682065787065637465646044820152606401610386565b8060405160200161091b9190610fd8565b60405160208183030381529060405280519060200120826040516020016109429190610fd8565b604051602081830303815290604052805190602001201461086b5760405162461bcd60e51b815260206004820152601c60248201527f486f737420646f6573206e6f74206d61746368206578706563746564000000006044820152606401610386565b60035460405163169394bb60e01b8152600481018390526001600160a01b039091169063169394bb90602401602060405180830381865afa1580156109ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a12919061139c565b15610a5f5760405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e2075736564006044820152606401610386565b600354604051632dea6f9960e11b8152600481018390526001600160a01b0390911690635bd4df3290602401600060405180830381600087803b158015610aa557600080fd5b505af1158015610ab9573d6000803e3d6000fd5b5050505050565b6000610ad183601760f91b84610b2c565b9392505050565b825160208401207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c8120610b236001600160a01b0384168286610d09565b95945050505050565b600083818080805b8451811015610c8257603060f81b858281518110610b5457610b546113be565b01602001516001600160f81b03191610801590610b955750603960f81b858281518110610b8357610b836113be565b01602001516001600160f81b03191611155b15610bd8576030858281518110610bae57610bae6113be565b0160200151610bc0919060f81c6113ea565b610bcb85600a6113fd565b610bd59190611414565b93505b8115610bec5782610be881611427565b9350505b876001600160f81b031916858281518110610c0957610c096113be565b01602001516001600160f81b03191603610c70578115610c6b5760405162461bcd60e51b815260206004820152601c60248201527f537472696e6720686173206d756c7469706c6520646563696d616c73000000006044820152606401610386565b600191505b80610c7a81611427565b915050610b34565b5085821115610cde5760405162461bcd60e51b815260206004820152602260248201527f537472696e672068617320746f6f206d616e7920646563696d616c20706c6163604482015261657360f01b6064820152608401610386565b610ce882876113ea565b610cf390600a611524565b610cfd90846113fd565b98975050505050505050565b6000806000610d188585610d6a565b90925090506000816004811115610d3157610d31611530565b148015610d4f5750856001600160a01b0316826001600160a01b0316145b80610d605750610d60868686610daf565b9695505050505050565b6000808251604103610da05760208301516040840151606085015160001a610d9487828585610e9b565b94509450505050610da8565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b8686604051602401610dd9929190611546565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610e179190611567565b600060405180830381855afa9150503d8060008114610e52576040519150601f19603f3d011682016040523d82523d6000602084013e610e57565b606091505b5091509150818015610e6b57506020815110155b8015610d6057508051630b135d3f60e11b90610e909083016020908101908401611579565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610ed25750600090506003610f56565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610f26573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610f4f57600060019250925050610f56565b9150600090505b94509492505050565b600060208284031215610f7157600080fd5b81356001600160a01b0381168114610ad157600080fd5b60005b83811015610fa3578181015183820152602001610f8b565b50506000910152565b60008151808452610fc4816020860160208601610f88565b601f01601f19169290920160200192915050565b602081526000610ad16020830184610fac565b600060208284031215610ffd57600080fd5b813567ffffffffffffffff81111561101457600080fd5b820160408185031215610ad157600080fd5b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561105f5761105f611026565b60405290565b600067ffffffffffffffff8084111561108057611080611026565b604051601f8501601f19908116603f011681019082821181831017156110a8576110a8611026565b816040528093508581528686860111156110c157600080fd5b858560208301376000602087830101525050509392505050565b600082601f8301126110ec57600080fd5b610ad183833560208501611065565b60006080828403121561110d57600080fd5b61111561103c565b9050813567ffffffffffffffff8082111561112f57600080fd5b61113b858386016110db565b8352602084013591508082111561115157600080fd5b61115d858386016110db565b6020840152604084013591508082111561117657600080fd5b611182858386016110db565b6040840152606084013591508082111561119b57600080fd5b506111a8848285016110db565b60608301525092915050565b600080604083850312156111c757600080fd5b823567ffffffffffffffff808211156111df57600080fd5b6111eb868387016110fb565b9350602085013591508082111561120157600080fd5b508301601f8101851361121357600080fd5b61122285823560208401611065565b9150509250929050565b60006020828403121561123e57600080fd5b5035919050565b600181811c9082168061125957607f821691505b60208210810361127957634e487b7160e01b600052602260045260246000fd5b50919050565b60008235607e1983360301811261129557600080fd5b9190910192915050565b60006106d236836110fb565b6000808335601e198436030181126112c257600080fd5b83018035915067ffffffffffffffff8211156112dd57600080fd5b602001915036819003821315610da857600080fd5b60408152600c60408201526b3932b3b4b9ba3930ba34b7b760a11b606082015260806020820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101919050565b6080815260006113576080830187610fac565b82810360208401526113698187610fac565b9050828103604084015261137d8186610fac565b905082810360608401526113918185610fac565b979650505050505050565b6000602082840312156113ae57600080fd5b81518015158114610ad157600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b818103818111156106d2576106d26113d4565b80820281158282048414176106d2576106d26113d4565b808201808211156106d2576106d26113d4565b600060018201611439576114396113d4565b5060010190565b600181815b8085111561147b578160001904821115611461576114616113d4565b8085161561146e57918102915b93841c9390800290611445565b509250929050565b600082611492575060016106d2565b8161149f575060006106d2565b81600181146114b557600281146114bf576114db565b60019150506106d2565b60ff8411156114d0576114d06113d4565b50506001821b6106d2565b5060208310610133831016604e8410600b84101617156114fe575081810a6106d2565b6115088383611440565b806000190482111561151c5761151c6113d4565b029392505050565b6000610ad18383611483565b634e487b7160e01b600052602160045260246000fd5b82815260406020820152600061155f6040830184610fac565b949350505050565b60008251611295818460208701610f88565b60006020828403121561158b57600080fd5b505191905056fea26469706673582212203e98302b127b19eb5c2f90167d93f78ee198dd9265bb36ff80173ab3384c571164736f6c63430008120033", + "solcInputHash": "0de631e329f560f49e3d6a21d19a30cc", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_ramp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"},{\"internalType\":\"contract INullifierRegistry\",\"name\":\"_nullifierRegistry\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_host\",\"type\":\"string\"}],\"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\":false,\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"}],\"name\":\"VerifierSigningKeySet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"endpoint\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"host\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nullifierRegistry\",\"outputs\":[{\"internalType\":\"contract INullifierRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"profileId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"wiseTagHash\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"userAddress\",\"type\":\"address\"}],\"internalType\":\"struct IWiseAccountRegistrationProcessor.RegistrationData\",\"name\":\"public_values\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"internalType\":\"struct IWiseAccountRegistrationProcessor.RegistrationProof\",\"name\":\"_proof\",\"type\":\"tuple\"}],\"name\":\"processProof\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"onRampId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"wiseTagHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ramp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"}],\"name\":\"setTimestampBuffer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"}],\"name\":\"setVerifierSigningKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timestampBuffer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verifierSigningKey\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"profileId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"wiseTagHash\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"userAddress\",\"type\":\"address\"}],\"internalType\":\"struct IWiseAccountRegistrationProcessor.RegistrationData\",\"name\":\"_publicValues\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"_proof\",\"type\":\"bytes\"}],\"name\":\"verifyProof\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setTimestampBuffer(uint256)\":{\"params\":{\"_timestampBuffer\":\"The timestamp buffer for validated TLS calls\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"setTimestampBuffer(uint256)\":{\"notice\":\"ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2 timestamps.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ramps/wise/WiseAccountRegistrationProcessor.sol\":\"WiseAccountRegistrationProcessor\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"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/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/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"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\"},\"contracts/lib/StringConversionUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\n// Building on zk-email's StringUtils library we add the ability to handle decimals when\\n// converting from string to Uint\\nlibrary StringConversionUtils {\\n \\n /**\\n * @notice Function that parses numbers returned as strings including floating point numbers. Returned floating point\\n * numbers are to have the desired amount of decimal specified. If the stringified version of the floating point\\n * number has more decimal places than desired then the function will revert in order to be maximally safe. If\\n * the returned number has multiple floating points then the function will revert.\\n *\\n * Examples: _s = \\\"12.34\\\", _expectedDecimals = 6 => 12340000\\n * _s = \\\"12.34\\\", _expectedDecimals = 2 => 1234\\n * _s = \\\"12.34\\\", _expectedDecimals = 1 => REVERT (we never want loss of precision only addition)\\n * _s = \\\"12.34.56\\\", _expectedDecimals = 6 => REVERT (Invalid number)\\n *\\n * @param _s String being processed\\n * @param _desiredDecimals Desired amount of decimal places\\n */\\n function stringToUint(string memory _s, uint256 _desiredDecimals) internal pure returns (uint256) {\\n return stringToUint(_s, 0x2E, _desiredDecimals);\\n }\\n\\n function stringToUint(\\n string memory _s,\\n bytes1 _decimalCharacter,\\n uint256 _desiredDecimals\\n )\\n internal\\n pure\\n returns (uint256)\\n {\\n bytes memory b = bytes(_s);\\n\\n uint256 result = 0;\\n uint256 decimalPlaces = 0;\\n\\n bool decimals = false;\\n for (uint256 i = 0; i < b.length; i++) {\\n if (b[i] >= 0x30 && b[i] <= 0x39) {\\n result = result * 10 + (uint256(uint8(b[i])) - 48);\\n }\\n\\n if (decimals) {\\n decimalPlaces++;\\n }\\n\\n if (b[i] == _decimalCharacter) {\\n require(decimals == false, \\\"String has multiple decimals\\\");\\n decimals = true;\\n }\\n }\\n\\n require(decimalPlaces <= _desiredDecimals, \\\"String has too many decimal places\\\");\\n return result * (10 ** (_desiredDecimals - decimalPlaces));\\n }\\n\\n /**\\n * @notice Function that returns a substring from _startIndex to _endIndex (non-inclusive).\\n *\\n * @param _str String being processed\\n * @param _startIndex Index to start parsing from\\n * @param _endIndex Index to stop parsing at (index not included in result)\\n */\\n function substring(string memory _str, uint _startIndex, uint _endIndex) internal pure returns (string memory ) {\\n bytes memory strBytes = bytes(_str);\\n bytes memory result = new bytes(_endIndex-_startIndex);\\n for(uint i = _startIndex; i < _endIndex; i++) {\\n result[i-_startIndex] = strBytes[i];\\n }\\n return string(result);\\n }\\n\\n function replaceString(\\n string memory _str,\\n string memory _lookupValue,\\n string memory _replaceValue\\n )\\n internal\\n pure\\n returns (string memory)\\n {\\n bytes memory strBytes = bytes(_str);\\n bytes memory lookupBytes = bytes(_lookupValue);\\n\\n uint256 lookupIndex = indexOf(_str, _lookupValue);\\n if (lookupIndex == type(uint256).max) {\\n return _str;\\n }\\n\\n // Split the original string into two parts: before and after the keyword\\n string memory beforeKeyword = substring(_str, 0, lookupIndex);\\n string memory afterKeyword = substring(_str, lookupIndex + lookupBytes.length, strBytes.length);\\n \\n return string.concat(beforeKeyword, _replaceValue, afterKeyword);\\n }\\n\\n function indexOf(string memory str, string memory substr) internal pure returns (uint) {\\n bytes memory strBytes = bytes(str);\\n bytes memory substrBytes = bytes(substr);\\n \\n if (strBytes.length < substrBytes.length) return type(uint256).max;\\n \\n for (uint i = 0; i <= strBytes.length - substrBytes.length; i++) {\\n bool found = true;\\n for (uint j = 0; j < substrBytes.length; j++) {\\n if (strBytes[i + j] != substrBytes[j]) {\\n found = false;\\n break;\\n }\\n }\\n if (found) return i;\\n }\\n \\n return type(uint256).max;\\n }\\n\\n function stringComparison(string memory _a, string memory _b) internal pure returns (bool) {\\n return (keccak256(abi.encodePacked(_a)) == keccak256(abi.encodePacked(_b)));\\n }\\n}\\n\",\"keccak256\":\"0xfcdfb3c2c8d5a6b7f480f827049782a70fb98f8b3838dcad0e0bb95237b94a0c\",\"license\":\"MIT\"},\"contracts/processors/TLSBaseProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { ECDSA } from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { SignatureChecker } from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\n\\nimport { INullifierRegistry } from \\\"./nullifierRegistries/INullifierRegistry.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract TLSBaseProcessor is Ownable {\\n\\n using SignatureChecker for address;\\n using ECDSA for bytes32;\\n\\n /* ============ Modifiers ============ */\\n modifier onlyRamp() {\\n require(msg.sender == ramp, \\\"Only Ramp can call this function\\\");\\n _;\\n }\\n\\n /* ============ State Variables ============ */\\n address public immutable ramp;\\n string public endpoint;\\n string public host;\\n\\n INullifierRegistry public nullifierRegistry;\\n uint256 public timestampBuffer;\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _ramp,\\n INullifierRegistry _nullifierRegistry,\\n uint256 _timestampBuffer,\\n string memory _endpoint,\\n string memory _host\\n )\\n Ownable()\\n {\\n ramp = _ramp;\\n endpoint = _endpoint;\\n host = _host;\\n\\n nullifierRegistry = _nullifierRegistry;\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ External Functions ============ */\\n\\n /**\\n * @notice ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds\\n * that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2\\n * timestamps.\\n *\\n * @param _timestampBuffer The timestamp buffer for validated TLS calls\\n */\\n function setTimestampBuffer(uint256 _timestampBuffer) external onlyOwner {\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ Internal Functions ============ */\\n\\n function _validateTLSEndpoint(\\n string memory _expectedEndpoint,\\n string memory _passedEndpoint\\n )\\n internal\\n pure\\n {\\n require(\\n keccak256(abi.encode(_expectedEndpoint)) == keccak256(abi.encode(_passedEndpoint)),\\n \\\"Endpoint does not match expected\\\"\\n );\\n }\\n\\n function _validateTLSHost(\\n string memory _expectedHost,\\n string memory _passedHost\\n )\\n internal\\n pure\\n {\\n require(\\n keccak256(abi.encode(_expectedHost)) == keccak256(abi.encode(_passedHost)),\\n \\\"Host does not match expected\\\"\\n );\\n }\\n\\n function _validateAndAddNullifier(bytes32 _nullifier) internal {\\n require(!nullifierRegistry.isNullified(_nullifier), \\\"Nullifier has already been used\\\");\\n nullifierRegistry.addNullifier(_nullifier);\\n }\\n\\n function _isValidVerifierSignature(\\n bytes memory _message,\\n bytes memory _signature,\\n address _verifier\\n )\\n internal\\n view\\n returns(bool)\\n {\\n bytes32 verifierPayload = keccak256(_message).toEthSignedMessageHash();\\n\\n return _verifier.isValidSignatureNow(verifierPayload, _signature);\\n }\\n}\\n\",\"keccak256\":\"0xbbdb8f203288645916ad04ee65625fae570ed091fbf243a706df7991b29ffe61\",\"license\":\"MIT\"},\"contracts/processors/nullifierRegistries/INullifierRegistry.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface INullifierRegistry {\\n function addNullifier(bytes32 _nullifier) external;\\n function isNullified(bytes32 _nullifier) external view returns(bool);\\n}\\n\",\"keccak256\":\"0x107164bc9a320938b513305878163b7fa884da4cdae58d0c8e81bfbb00c97c5e\",\"license\":\"MIT\"},\"contracts/ramps/wise/WiseAccountRegistrationProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { ECDSA } from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport { SignatureChecker } from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\n\\nimport { INullifierRegistry } from \\\"../../processors/nullifierRegistries/INullifierRegistry.sol\\\";\\nimport { IWiseAccountRegistrationProcessor } from \\\"./interfaces/IWiseAccountRegistrationProcessor.sol\\\";\\nimport { StringConversionUtils } from \\\"../../lib/StringConversionUtils.sol\\\";\\nimport { TLSBaseProcessor } from \\\"../../processors/TLSBaseProcessor.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract WiseAccountRegistrationProcessor is IWiseAccountRegistrationProcessor, TLSBaseProcessor {\\n\\n using ECDSA for bytes32;\\n using SignatureChecker for address;\\n using StringConversionUtils for string;\\n \\n /* ============ Events ============ */\\n event VerifierSigningKeySet(address _verifierSigningKey);\\n \\n /* ============ Public Variables ============ */\\n address public verifierSigningKey;\\n \\n /* ============ Constructor ============ */\\n constructor(\\n address _ramp,\\n address _verifierSigningKey,\\n INullifierRegistry _nullifierRegistry,\\n uint256 _timestampBuffer,\\n string memory _endpoint,\\n string memory _host\\n )\\n TLSBaseProcessor(\\n _ramp,\\n _nullifierRegistry,\\n _timestampBuffer,\\n _endpoint,\\n _host\\n )\\n {\\n verifierSigningKey = _verifierSigningKey;\\n }\\n\\n /* ============ External Functions ============ */\\n\\n function processProof(\\n IWiseAccountRegistrationProcessor.RegistrationProof calldata _proof\\n )\\n public\\n override\\n onlyRamp\\n returns(bytes32 onRampId, bytes32 wiseTagHash)\\n {\\n _validateProof(_proof.public_values, _proof.proof);\\n\\n _validateTLSEndpoint(endpoint, _proof.public_values.endpoint);\\n _validateTLSHost(host, _proof.public_values.host);\\n\\n _validateAndAddNullifier(keccak256(abi.encode(_proof.public_values.userAddress, _proof.public_values.profileId)));\\n\\n onRampId = bytes32(_proof.public_values.profileId.stringToUint(0));\\n wiseTagHash = bytes32(_proof.public_values.wiseTagHash.stringToUint(0));\\n }\\n\\n /* ============ External Admin Functions ============ */\\n\\n function setVerifierSigningKey(address _verifierSigningKey) external onlyOwner {\\n verifierSigningKey = _verifierSigningKey;\\n\\n emit VerifierSigningKeySet(_verifierSigningKey);\\n }\\n\\n /* ============ View Functions ============ */\\n\\n function verifyProof(\\n IWiseAccountRegistrationProcessor.RegistrationData memory _publicValues,\\n bytes memory _proof\\n )\\n public\\n view\\n returns(bool)\\n {\\n bytes memory encodedMessage = abi.encode(\\n _publicValues.endpoint,\\n _publicValues.host,\\n _publicValues.profileId,\\n _publicValues.wiseTagHash,\\n _publicValues.userAddress\\n );\\n return _isValidVerifierSignature(encodedMessage, _proof, verifierSigningKey);\\n }\\n \\n /* ============ Internal Functions ============ */\\n\\n function _validateProof(\\n IWiseAccountRegistrationProcessor.RegistrationData memory _publicValues, \\n bytes memory _proof\\n )\\n internal\\n view\\n { \\n require(\\n verifyProof(_publicValues, _proof),\\n \\\"Invalid signature from verifier\\\"\\n );\\n }\\n}\\n\",\"keccak256\":\"0xc7a7d5e0d3801e67c85ab7cc64120c71532cd150bf835c7135f4c52339ebe72e\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseAccountRegistrationProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseAccountRegistrationProcessor {\\n\\n struct RegistrationData {\\n string endpoint;\\n string host;\\n string profileId;\\n string wiseTagHash;\\n address userAddress;\\n }\\n\\n struct RegistrationProof {\\n RegistrationData public_values;\\n bytes proof;\\n }\\n\\n function processProof(\\n RegistrationProof calldata _proof\\n )\\n external\\n returns (bytes32, bytes32);\\n}\\n\",\"keccak256\":\"0x2a8373601ac246f684f1a92b111a245fe3c6d3d57d6abcb4e00bd8eeae734631\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162001a1a38038062001a1a8339810160408190526200003491620001e2565b85848484846200004433620000b4565b6001600160a01b03851660805260016200005f838262000324565b5060026200006e828262000324565b5050600380546001600160a01b039485166001600160a01b03199182161790915560049290925550600580549890921697169690961790955550620003f0945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200011a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200014557600080fd5b81516001600160401b03808211156200016257620001626200011d565b604051601f8301601f19908116603f011681019082821181831017156200018d576200018d6200011d565b81604052838152602092508683858801011115620001aa57600080fd5b600091505b83821015620001ce5785820183015181830184015290820190620001af565b600093810190920192909252949350505050565b60008060008060008060c08789031215620001fc57600080fd5b8651620002098162000104565b60208801519096506200021c8162000104565b60408801519095506200022f8162000104565b6060880151608089015191955093506001600160401b03808211156200025457600080fd5b620002628a838b0162000133565b935060a08901519150808211156200027957600080fd5b506200028889828a0162000133565b9150509295509295509295565b600181811c90821680620002aa57607f821691505b602082108103620002cb57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200031f57600081815260208120601f850160051c81016020861015620002fa5750805b601f850160051c820191505b818110156200031b5782815560010162000306565b5050505b505050565b81516001600160401b038111156200034057620003406200011d565b620003588162000351845462000295565b84620002d1565b602080601f831160018114620003905760008415620003775750858301515b600019600386901b1c1916600185901b1785556200031b565b600085815260208120601f198616915b82811015620003c157888601518255948401946001909101908401620003a0565b5085821015620003e05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516116076200041360003960008181610109015261027b01526116076000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c80638da5cb5b1161008c578063d2292bab11610066578063d2292bab146101bc578063dbac5821146101df578063f2fde38b146101f6578063f437bc591461020957600080fd5b80638da5cb5b14610185578063b2a3fda414610196578063b870676c146101a957600080fd5b80630fa4ed4d146100d457806315d276e1146101045780634e06a32b1461012b5780635e0b6e9b146101405780635e280f1114610168578063715018a61461017d575b600080fd5b6005546100e7906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100e77f000000000000000000000000000000000000000000000000000000000000000081565b61013e610139366004610f9d565b610211565b005b61015361014e366004610fb8565b61026d565b604080519283526020830191909152016100fb565b6101706105f2565b6040516100fb9190611043565b61013e610680565b6000546001600160a01b03166100e7565b61013e6101a4366004611056565b610694565b6003546100e7906001600160a01b031681565b6101cf6101ca36600461120e565b6106a1565b60405190151581526020016100fb565b6101e860045481565b6040519081526020016100fb565b61013e610204366004610f9d565b610707565b610170610780565b61021961078d565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fb8603ceabf8ee4633f1fd8c0ae9e0e64f2fc2fea5cb79a96c18efd007aab6f969060200160405180910390a150565b600080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102ed5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792052616d702063616e2063616c6c20746869732066756e6374696f6e60448201526064015b60405180910390fd5b61034a6102fa8480611286565b610303906112a6565b61031060208601866112b2565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506107e792505050565b61042a6001805461035a906112f9565b80601f0160208091040260200160405190810160405280929190818152602001828054610386906112f9565b80156103d35780601f106103a8576101008083540402835291602001916103d3565b820191906000526020600020905b8154815290600101906020018083116103b657829003601f168201915b506103e693508892508291506112869050565b6103f090806112b2565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061084192505050565b61050e6002805461043a906112f9565b80601f0160208091040260200160405190810160405280929190818152602001828054610466906112f9565b80156104b35780601f10610488576101008083540402835291602001916104b3565b820191906000526020600020905b81548152906001019060200180831161049657829003601f168201915b506104c693508892508291506112869050565b6104d49060208101906112b2565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506108dc92505050565b61057161051b8480611286565b61052c9060a0810190608001610f9d565b6105368580611286565b6105449060408101906112b2565b60405160200161055693929190611333565b60405160208183030381529060405280519060200120610977565b6105cb60006105808580611286565b61058e9060408101906112b2565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293925050610a929050565b91506105ea60006105dc8580611286565b61058e9060608101906112b2565b919391925050565b600180546105ff906112f9565b80601f016020809104026020016040519081016040528092919081815260200182805461062b906112f9565b80156106785780601f1061064d57610100808354040283529160200191610678565b820191906000526020600020905b81548152906001019060200180831161065b57829003601f168201915b505050505081565b61068861078d565b6106926000610aaa565b565b61069c61078d565b600455565b600080836000015184602001518560400151866060015187608001516040516020016106d1959493929190611373565b60408051601f198184030181529190526005549091506106fd90829085906001600160a01b0316610afa565b9150505b92915050565b61070f61078d565b6001600160a01b0381166107745760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102e4565b61077d81610aaa565b50565b600280546105ff906112f9565b6000546001600160a01b031633146106925760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6107f182826106a1565b61083d5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e61747572652066726f6d2076657269666965720060448201526064016102e4565b5050565b806040516020016108529190611043565b60405160208183030381529060405280519060200120826040516020016108799190611043565b604051602081830303815290604052805190602001201461083d5760405162461bcd60e51b815260206004820181905260248201527f456e64706f696e7420646f6573206e6f74206d6174636820657870656374656460448201526064016102e4565b806040516020016108ed9190611043565b60405160208183030381529060405280519060200120826040516020016109149190611043565b604051602081830303815290604052805190602001201461083d5760405162461bcd60e51b815260206004820152601c60248201527f486f737420646f6573206e6f74206d617463682065787065637465640000000060448201526064016102e4565b60035460405163169394bb60e01b8152600481018390526001600160a01b039091169063169394bb90602401602060405180830381865afa1580156109c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e491906113db565b15610a315760405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e20757365640060448201526064016102e4565b600354604051632dea6f9960e11b8152600481018390526001600160a01b0390911690635bd4df3290602401600060405180830381600087803b158015610a7757600080fd5b505af1158015610a8b573d6000803e3d6000fd5b5050505050565b6000610aa383601760f91b84610b4e565b9392505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b825160208401207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c8120610b456001600160a01b0384168286610d2b565b95945050505050565b600083818080805b8451811015610ca457603060f81b858281518110610b7657610b766113fd565b01602001516001600160f81b03191610801590610bb75750603960f81b858281518110610ba557610ba56113fd565b01602001516001600160f81b03191611155b15610bfa576030858281518110610bd057610bd06113fd565b0160200151610be2919060f81c611429565b610bed85600a61143c565b610bf79190611453565b93505b8115610c0e5782610c0a81611466565b9350505b876001600160f81b031916858281518110610c2b57610c2b6113fd565b01602001516001600160f81b03191603610c92578115610c8d5760405162461bcd60e51b815260206004820152601c60248201527f537472696e6720686173206d756c7469706c6520646563696d616c730000000060448201526064016102e4565b600191505b80610c9c81611466565b915050610b56565b5085821115610d005760405162461bcd60e51b815260206004820152602260248201527f537472696e672068617320746f6f206d616e7920646563696d616c20706c6163604482015261657360f01b60648201526084016102e4565b610d0a8287611429565b610d1590600a611563565b610d1f908461143c565b98975050505050505050565b6000806000610d3a8585610d8c565b90925090506000816004811115610d5357610d5361156f565b148015610d715750856001600160a01b0316826001600160a01b0316145b80610d825750610d82868686610dd1565b9695505050505050565b6000808251604103610dc25760208301516040840151606085015160001a610db687828585610ebd565b94509450505050610dca565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b8686604051602401610dfb929190611585565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610e3991906115a6565b600060405180830381855afa9150503d8060008114610e74576040519150601f19603f3d011682016040523d82523d6000602084013e610e79565b606091505b5091509150818015610e8d57506020815110155b8015610d8257508051630b135d3f60e11b90610eb290830160209081019084016115b8565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610ef45750600090506003610f78565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610f48573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610f7157600060019250925050610f78565b9150600090505b94509492505050565b80356001600160a01b0381168114610f9857600080fd5b919050565b600060208284031215610faf57600080fd5b610aa382610f81565b600060208284031215610fca57600080fd5b813567ffffffffffffffff811115610fe157600080fd5b820160408185031215610aa357600080fd5b60005b8381101561100e578181015183820152602001610ff6565b50506000910152565b6000815180845261102f816020860160208601610ff3565b601f01601f19169290920160200192915050565b602081526000610aa36020830184611017565b60006020828403121561106857600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156110a8576110a861106f565b60405290565b600067ffffffffffffffff808411156110c9576110c961106f565b604051601f8501601f19908116603f011681019082821181831017156110f1576110f161106f565b8160405280935085815286868601111561110a57600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261113557600080fd5b610aa3838335602085016110ae565b600060a0828403121561115657600080fd5b61115e611085565b9050813567ffffffffffffffff8082111561117857600080fd5b61118485838601611124565b8352602084013591508082111561119a57600080fd5b6111a685838601611124565b602084015260408401359150808211156111bf57600080fd5b6111cb85838601611124565b604084015260608401359150808211156111e457600080fd5b506111f184828501611124565b60608301525061120360808301610f81565b608082015292915050565b6000806040838503121561122157600080fd5b823567ffffffffffffffff8082111561123957600080fd5b61124586838701611144565b9350602085013591508082111561125b57600080fd5b508301601f8101851361126d57600080fd5b61127c858235602084016110ae565b9150509250929050565b60008235609e1983360301811261129c57600080fd5b9190910192915050565b60006107013683611144565b6000808335601e198436030181126112c957600080fd5b83018035915067ffffffffffffffff8211156112e457600080fd5b602001915036819003821315610dca57600080fd5b600181811c9082168061130d57607f821691505b60208210810361132d57634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b03841681526040602082018190528101829052818360608301376000818301606090810191909152601f909201601f1916010192915050565b60a08152600061138660a0830188611017565b82810360208401526113988188611017565b905082810360408401526113ac8187611017565b905082810360608401526113c08186611017565b91505060018060a01b03831660808301529695505050505050565b6000602082840312156113ed57600080fd5b81518015158114610aa357600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561070157610701611413565b808202811582820484141761070157610701611413565b8082018082111561070157610701611413565b60006001820161147857611478611413565b5060010190565b600181815b808511156114ba5781600019048211156114a0576114a0611413565b808516156114ad57918102915b93841c9390800290611484565b509250929050565b6000826114d157506001610701565b816114de57506000610701565b81600181146114f457600281146114fe5761151a565b6001915050610701565b60ff84111561150f5761150f611413565b50506001821b610701565b5060208310610133831016604e8410600b841016171561153d575081810a610701565b611547838361147f565b806000190482111561155b5761155b611413565b029392505050565b6000610aa383836114c2565b634e487b7160e01b600052602160045260246000fd5b82815260406020820152600061159e6040830184611017565b949350505050565b6000825161129c818460208701610ff3565b6000602082840312156115ca57600080fd5b505191905056fea26469706673582212202f964d5a2492da66715150a91e86421060b8f263eece87c6fd58e0f3251faa0864736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c80638da5cb5b1161008c578063d2292bab11610066578063d2292bab146101bc578063dbac5821146101df578063f2fde38b146101f6578063f437bc591461020957600080fd5b80638da5cb5b14610185578063b2a3fda414610196578063b870676c146101a957600080fd5b80630fa4ed4d146100d457806315d276e1146101045780634e06a32b1461012b5780635e0b6e9b146101405780635e280f1114610168578063715018a61461017d575b600080fd5b6005546100e7906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100e77f000000000000000000000000000000000000000000000000000000000000000081565b61013e610139366004610f9d565b610211565b005b61015361014e366004610fb8565b61026d565b604080519283526020830191909152016100fb565b6101706105f2565b6040516100fb9190611043565b61013e610680565b6000546001600160a01b03166100e7565b61013e6101a4366004611056565b610694565b6003546100e7906001600160a01b031681565b6101cf6101ca36600461120e565b6106a1565b60405190151581526020016100fb565b6101e860045481565b6040519081526020016100fb565b61013e610204366004610f9d565b610707565b610170610780565b61021961078d565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fb8603ceabf8ee4633f1fd8c0ae9e0e64f2fc2fea5cb79a96c18efd007aab6f969060200160405180910390a150565b600080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102ed5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792052616d702063616e2063616c6c20746869732066756e6374696f6e60448201526064015b60405180910390fd5b61034a6102fa8480611286565b610303906112a6565b61031060208601866112b2565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506107e792505050565b61042a6001805461035a906112f9565b80601f0160208091040260200160405190810160405280929190818152602001828054610386906112f9565b80156103d35780601f106103a8576101008083540402835291602001916103d3565b820191906000526020600020905b8154815290600101906020018083116103b657829003601f168201915b506103e693508892508291506112869050565b6103f090806112b2565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061084192505050565b61050e6002805461043a906112f9565b80601f0160208091040260200160405190810160405280929190818152602001828054610466906112f9565b80156104b35780601f10610488576101008083540402835291602001916104b3565b820191906000526020600020905b81548152906001019060200180831161049657829003601f168201915b506104c693508892508291506112869050565b6104d49060208101906112b2565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506108dc92505050565b61057161051b8480611286565b61052c9060a0810190608001610f9d565b6105368580611286565b6105449060408101906112b2565b60405160200161055693929190611333565b60405160208183030381529060405280519060200120610977565b6105cb60006105808580611286565b61058e9060408101906112b2565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293925050610a929050565b91506105ea60006105dc8580611286565b61058e9060608101906112b2565b919391925050565b600180546105ff906112f9565b80601f016020809104026020016040519081016040528092919081815260200182805461062b906112f9565b80156106785780601f1061064d57610100808354040283529160200191610678565b820191906000526020600020905b81548152906001019060200180831161065b57829003601f168201915b505050505081565b61068861078d565b6106926000610aaa565b565b61069c61078d565b600455565b600080836000015184602001518560400151866060015187608001516040516020016106d1959493929190611373565b60408051601f198184030181529190526005549091506106fd90829085906001600160a01b0316610afa565b9150505b92915050565b61070f61078d565b6001600160a01b0381166107745760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102e4565b61077d81610aaa565b50565b600280546105ff906112f9565b6000546001600160a01b031633146106925760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e4565b6107f182826106a1565b61083d5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e61747572652066726f6d2076657269666965720060448201526064016102e4565b5050565b806040516020016108529190611043565b60405160208183030381529060405280519060200120826040516020016108799190611043565b604051602081830303815290604052805190602001201461083d5760405162461bcd60e51b815260206004820181905260248201527f456e64706f696e7420646f6573206e6f74206d6174636820657870656374656460448201526064016102e4565b806040516020016108ed9190611043565b60405160208183030381529060405280519060200120826040516020016109149190611043565b604051602081830303815290604052805190602001201461083d5760405162461bcd60e51b815260206004820152601c60248201527f486f737420646f6573206e6f74206d617463682065787065637465640000000060448201526064016102e4565b60035460405163169394bb60e01b8152600481018390526001600160a01b039091169063169394bb90602401602060405180830381865afa1580156109c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e491906113db565b15610a315760405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e20757365640060448201526064016102e4565b600354604051632dea6f9960e11b8152600481018390526001600160a01b0390911690635bd4df3290602401600060405180830381600087803b158015610a7757600080fd5b505af1158015610a8b573d6000803e3d6000fd5b5050505050565b6000610aa383601760f91b84610b4e565b9392505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b825160208401207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c8120610b456001600160a01b0384168286610d2b565b95945050505050565b600083818080805b8451811015610ca457603060f81b858281518110610b7657610b766113fd565b01602001516001600160f81b03191610801590610bb75750603960f81b858281518110610ba557610ba56113fd565b01602001516001600160f81b03191611155b15610bfa576030858281518110610bd057610bd06113fd565b0160200151610be2919060f81c611429565b610bed85600a61143c565b610bf79190611453565b93505b8115610c0e5782610c0a81611466565b9350505b876001600160f81b031916858281518110610c2b57610c2b6113fd565b01602001516001600160f81b03191603610c92578115610c8d5760405162461bcd60e51b815260206004820152601c60248201527f537472696e6720686173206d756c7469706c6520646563696d616c730000000060448201526064016102e4565b600191505b80610c9c81611466565b915050610b56565b5085821115610d005760405162461bcd60e51b815260206004820152602260248201527f537472696e672068617320746f6f206d616e7920646563696d616c20706c6163604482015261657360f01b60648201526084016102e4565b610d0a8287611429565b610d1590600a611563565b610d1f908461143c565b98975050505050505050565b6000806000610d3a8585610d8c565b90925090506000816004811115610d5357610d5361156f565b148015610d715750856001600160a01b0316826001600160a01b0316145b80610d825750610d82868686610dd1565b9695505050505050565b6000808251604103610dc25760208301516040840151606085015160001a610db687828585610ebd565b94509450505050610dca565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b8686604051602401610dfb929190611585565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610e3991906115a6565b600060405180830381855afa9150503d8060008114610e74576040519150601f19603f3d011682016040523d82523d6000602084013e610e79565b606091505b5091509150818015610e8d57506020815110155b8015610d8257508051630b135d3f60e11b90610eb290830160209081019084016115b8565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610ef45750600090506003610f78565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610f48573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610f7157600060019250925050610f78565b9150600090505b94509492505050565b80356001600160a01b0381168114610f9857600080fd5b919050565b600060208284031215610faf57600080fd5b610aa382610f81565b600060208284031215610fca57600080fd5b813567ffffffffffffffff811115610fe157600080fd5b820160408185031215610aa357600080fd5b60005b8381101561100e578181015183820152602001610ff6565b50506000910152565b6000815180845261102f816020860160208601610ff3565b601f01601f19169290920160200192915050565b602081526000610aa36020830184611017565b60006020828403121561106857600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156110a8576110a861106f565b60405290565b600067ffffffffffffffff808411156110c9576110c961106f565b604051601f8501601f19908116603f011681019082821181831017156110f1576110f161106f565b8160405280935085815286868601111561110a57600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261113557600080fd5b610aa3838335602085016110ae565b600060a0828403121561115657600080fd5b61115e611085565b9050813567ffffffffffffffff8082111561117857600080fd5b61118485838601611124565b8352602084013591508082111561119a57600080fd5b6111a685838601611124565b602084015260408401359150808211156111bf57600080fd5b6111cb85838601611124565b604084015260608401359150808211156111e457600080fd5b506111f184828501611124565b60608301525061120360808301610f81565b608082015292915050565b6000806040838503121561122157600080fd5b823567ffffffffffffffff8082111561123957600080fd5b61124586838701611144565b9350602085013591508082111561125b57600080fd5b508301601f8101851361126d57600080fd5b61127c858235602084016110ae565b9150509250929050565b60008235609e1983360301811261129c57600080fd5b9190910192915050565b60006107013683611144565b6000808335601e198436030181126112c957600080fd5b83018035915067ffffffffffffffff8211156112e457600080fd5b602001915036819003821315610dca57600080fd5b600181811c9082168061130d57607f821691505b60208210810361132d57634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b03841681526040602082018190528101829052818360608301376000818301606090810191909152601f909201601f1916010192915050565b60a08152600061138660a0830188611017565b82810360208401526113988188611017565b905082810360408401526113ac8187611017565b905082810360608401526113c08186611017565b91505060018060a01b03831660808301529695505050505050565b6000602082840312156113ed57600080fd5b81518015158114610aa357600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561070157610701611413565b808202811582820484141761070157610701611413565b8082018082111561070157610701611413565b60006001820161147857611478611413565b5060010190565b600181815b808511156114ba5781600019048211156114a0576114a0611413565b808516156114ad57918102915b93841c9390800290611484565b509250929050565b6000826114d157506001610701565b816114de57506000610701565b81600181146114f457600281146114fe5761151a565b6001915050610701565b60ff84111561150f5761150f611413565b50506001821b610701565b5060208310610133831016604e8410600b841016171561153d575081810a610701565b611547838361147f565b806000190482111561155b5761155b611413565b029392505050565b6000610aa383836114c2565b634e487b7160e01b600052602160045260246000fd5b82815260406020820152600061159e6040830184611017565b949350505050565b6000825161129c818460208701610ff3565b6000602082840312156115ca57600080fd5b505191905056fea26469706673582212202f964d5a2492da66715150a91e86421060b8f263eece87c6fd58e0f3251faa0864736f6c63430008120033", "devdoc": { "kind": "dev", "methods": { @@ -395,7 +405,7 @@ "type": "t_address" }, { - "astId": 5432, + "astId": 2831, "contract": "contracts/ramps/wise/WiseAccountRegistrationProcessor.sol:WiseAccountRegistrationProcessor", "label": "endpoint", "offset": 0, @@ -403,7 +413,7 @@ "type": "t_string_storage" }, { - "astId": 5434, + "astId": 2833, "contract": "contracts/ramps/wise/WiseAccountRegistrationProcessor.sol:WiseAccountRegistrationProcessor", "label": "host", "offset": 0, @@ -411,15 +421,15 @@ "type": "t_string_storage" }, { - "astId": 5437, + "astId": 2836, "contract": "contracts/ramps/wise/WiseAccountRegistrationProcessor.sol:WiseAccountRegistrationProcessor", "label": "nullifierRegistry", "offset": 0, "slot": "3", - "type": "t_contract(INullifierRegistry)5831" + "type": "t_contract(INullifierRegistry)3027" }, { - "astId": 5439, + "astId": 2838, "contract": "contracts/ramps/wise/WiseAccountRegistrationProcessor.sol:WiseAccountRegistrationProcessor", "label": "timestampBuffer", "offset": 0, @@ -427,7 +437,7 @@ "type": "t_uint256" }, { - "astId": 17781, + "astId": 3060, "contract": "contracts/ramps/wise/WiseAccountRegistrationProcessor.sol:WiseAccountRegistrationProcessor", "label": "verifierSigningKey", "offset": 0, @@ -441,7 +451,7 @@ "label": "address", "numberOfBytes": "20" }, - "t_contract(INullifierRegistry)5831": { + "t_contract(INullifierRegistry)3027": { "encoding": "inplace", "label": "contract INullifierRegistry", "numberOfBytes": "20" diff --git a/contracts/deployments/sepolia/WiseAccountRegistry.json b/contracts/deployments/sepolia/WiseAccountRegistry.json index 81b9efdd1..89f00f6e1 100644 --- a/contracts/deployments/sepolia/WiseAccountRegistry.json +++ b/contracts/deployments/sepolia/WiseAccountRegistry.json @@ -1,5 +1,5 @@ { - "address": "0x7eDD66B19A22293af86A2d96761FD7146BA3fF6c", + "address": "0xF44B36992B96043128A3240744Bfe9b070a098Fa", "abi": [ { "inputs": [ @@ -503,6 +503,11 @@ "internalType": "string", "name": "wiseTagHash", "type": "string" + }, + { + "internalType": "address", + "name": "userAddress", + "type": "address" } ], "internalType": "struct IWiseAccountRegistrationProcessor.RegistrationData", @@ -645,48 +650,48 @@ "type": "function" } ], - "transactionHash": "0x986ffbfad849c41320d0c722626895d6d812cd87537ce883d288aa565e6301e5", + "transactionHash": "0x692a72a41a4dd7d5adbf6ffe72053d8e2ec765436b86b3136d90be119a778c5b", "receipt": { "to": null, "from": "0x4e39cF8578698131c57404e8bc3eEC820EDa51d8", - "contractAddress": "0x7eDD66B19A22293af86A2d96761FD7146BA3fF6c", - "transactionIndex": 56, - "gasUsed": "1363580", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000120000000000000100000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000020000000000100000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc5b3a102d9fe341b7cf4a71e2897b5dd30e55344ed9bf03800b5feed05d0be07", - "transactionHash": "0x986ffbfad849c41320d0c722626895d6d812cd87537ce883d288aa565e6301e5", + "contractAddress": "0xF44B36992B96043128A3240744Bfe9b070a098Fa", + "transactionIndex": 29, + "gasUsed": "1454164", + "logsBloom": "0x00000000000000000000000000000000004000000000000000800000000000040000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000100000000000000000000000000000000080000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x0ca9bc72184d7cdde00eda3b745f82c826365be52ecf282a3b1b9b815e446f72", + "transactionHash": "0x692a72a41a4dd7d5adbf6ffe72053d8e2ec765436b86b3136d90be119a778c5b", "logs": [ { - "transactionIndex": 56, - "blockNumber": 5573233, - "transactionHash": "0x986ffbfad849c41320d0c722626895d6d812cd87537ce883d288aa565e6301e5", - "address": "0x7eDD66B19A22293af86A2d96761FD7146BA3fF6c", + "transactionIndex": 29, + "blockNumber": 5635193, + "transactionHash": "0x692a72a41a4dd7d5adbf6ffe72053d8e2ec765436b86b3136d90be119a778c5b", + "address": "0xF44B36992B96043128A3240744Bfe9b070a098Fa", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000004e39cf8578698131c57404e8bc3eec820eda51d8" ], "data": "0x", - "logIndex": 30, - "blockHash": "0xc5b3a102d9fe341b7cf4a71e2897b5dd30e55344ed9bf03800b5feed05d0be07" + "logIndex": 28, + "blockHash": "0x0ca9bc72184d7cdde00eda3b745f82c826365be52ecf282a3b1b9b815e446f72" }, { - "transactionIndex": 56, - "blockNumber": 5573233, - "transactionHash": "0x986ffbfad849c41320d0c722626895d6d812cd87537ce883d288aa565e6301e5", - "address": "0x7eDD66B19A22293af86A2d96761FD7146BA3fF6c", + "transactionIndex": 29, + "blockNumber": 5635193, + "transactionHash": "0x692a72a41a4dd7d5adbf6ffe72053d8e2ec765436b86b3136d90be119a778c5b", + "address": "0xF44B36992B96043128A3240744Bfe9b070a098Fa", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000004e39cf8578698131c57404e8bc3eec820eda51d8", "0x0000000000000000000000004e39cf8578698131c57404e8bc3eec820eda51d8" ], "data": "0x", - "logIndex": 31, - "blockHash": "0xc5b3a102d9fe341b7cf4a71e2897b5dd30e55344ed9bf03800b5feed05d0be07" + "logIndex": 29, + "blockHash": "0x0ca9bc72184d7cdde00eda3b745f82c826365be52ecf282a3b1b9b815e446f72" } ], - "blockNumber": 5573233, - "cumulativeGasUsed": "5596055", + "blockNumber": 5635193, + "cumulativeGasUsed": "4657554", "status": 1, "byzantium": true }, @@ -694,10 +699,10 @@ "0x4e39cF8578698131c57404e8bc3eEC820EDa51d8" ], "numDeployments": 1, - "solcInputHash": "6e4c0155cf194d54974389502ced73c2", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"accountOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"accountId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"wiseTagHash\",\"type\":\"bytes32\"}],\"name\":\"AccountRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"listOwner\",\"type\":\"bytes32\"}],\"name\":\"AllowlistEnabled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"registrationProcessor\",\"type\":\"address\"}],\"name\":\"NewAccountRegistrationProcessorSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"registrationProcessor\",\"type\":\"address\"}],\"name\":\"NewOffRamperRegistrationProcessorSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"accountOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"accountId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"offRampId\",\"type\":\"bytes32\"}],\"name\":\"OffRamperRegistered\",\"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\":\"bytes32\",\"name\":\"listOwner\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"allowedUser\",\"type\":\"bytes32\"}],\"name\":\"UserAddedToAllowlist\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"listOwner\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"deniedUser\",\"type\":\"bytes32\"}],\"name\":\"UserAddedToDenylist\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"listOwner\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"allowedUser\",\"type\":\"bytes32\"}],\"name\":\"UserRemovedFromAllowlist\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"listOwner\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"approvedUser\",\"type\":\"bytes32\"}],\"name\":\"UserRemovedFromDenylist\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountRegistrationProcessor\",\"outputs\":[{\"internalType\":\"contract IWiseAccountRegistrationProcessor\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_deniedUser\",\"type\":\"bytes32\"}],\"name\":\"addAccountToDenylist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"_allowedUsers\",\"type\":\"bytes32[]\"}],\"name\":\"addAccountsToAllowlist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"enableAllowlist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getAccountId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getAccountInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"accountId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"offRampId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"wiseTagHash\",\"type\":\"bytes32\"}],\"internalType\":\"struct IWiseAccountRegistry.AccountInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getAllowedUsers\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getDeniedUsers\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWiseAccountRegistrationProcessor\",\"name\":\"_accountRegistrationProcessor\",\"type\":\"address\"},{\"internalType\":\"contract IWiseOffRamperRegistrationProcessor\",\"name\":\"_offRamperRegistrationProcessor\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_allowedUser\",\"type\":\"bytes32\"}],\"name\":\"isAllowedUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"isAllowlistEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_deniedUser\",\"type\":\"bytes32\"}],\"name\":\"isDeniedUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"isRegisteredUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offRamperRegistrationProcessor\",\"outputs\":[{\"internalType\":\"contract IWiseOffRamperRegistrationProcessor\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"profileId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"wiseTagHash\",\"type\":\"string\"}],\"internalType\":\"struct IWiseAccountRegistrationProcessor.RegistrationData\",\"name\":\"public_values\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"internalType\":\"struct IWiseAccountRegistrationProcessor.RegistrationProof\",\"name\":\"_proof\",\"type\":\"tuple\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"profileId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"mcAccountId\",\"type\":\"string\"}],\"internalType\":\"struct IWiseOffRamperRegistrationProcessor.OffRamperRegistrationData\",\"name\":\"public_values\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"internalType\":\"struct IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof\",\"name\":\"_proof\",\"type\":\"tuple\"}],\"name\":\"registerAsOffRamper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_approvedUser\",\"type\":\"bytes32\"}],\"name\":\"removeAccountFromDenylist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"_disallowedUsers\",\"type\":\"bytes32[]\"}],\"name\":\"removeAccountsFromAllowlist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWiseAccountRegistrationProcessor\",\"name\":\"_registrationProcessor\",\"type\":\"address\"}],\"name\":\"setAccountRegistrationProcessor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWiseOffRamperRegistrationProcessor\",\"name\":\"_registrationProcessor\",\"type\":\"address\"}],\"name\":\"setOffRamperRegistrationProcessor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addAccountToDenylist(bytes32)\":{\"params\":{\"_deniedUser\":\"accountId being banned\"}},\"addAccountsToAllowlist(bytes32[])\":{\"params\":{\"_allowedUsers\":\"List of accountIds allowed to signal intents on the user's deposit\"}},\"initialize(address,address)\":{\"params\":{\"_accountRegistrationProcessor\":\"Account Registration processor address\",\"_offRamperRegistrationProcessor\":\"Off-ramper Registration processor address\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"register(((string,string,string,string),bytes))\":{\"params\":{\"_proof\":\"Registration proof consisting of unredacted data being notarized and a signature\"}},\"registerAsOffRamper(((string,string,string,string),bytes))\":{\"params\":{\"_proof\":\"Registration proof consisting of unredacted data being notarized and a signature\"}},\"removeAccountFromDenylist(bytes32)\":{\"params\":{\"_approvedUser\":\"accountId being approved\"}},\"removeAccountsFromAllowlist(bytes32[])\":{\"params\":{\"_disallowedUsers\":\"List of accountIds being approved\"}},\"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.\"},\"setAccountRegistrationProcessor(address)\":{\"params\":{\"_registrationProcessor\":\"New registration proccesor address\"}},\"setOffRamperRegistrationProcessor(address)\":{\"params\":{\"_registrationProcessor\":\"New registration proccesor address\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addAccountToDenylist(bytes32)\":{\"notice\":\"Adds an accountId to a depositor's deny list. If an address associated with the banned accountId attempts to signal an intent on the user's deposit they will be denied.\"},\"addAccountsToAllowlist(bytes32[])\":{\"notice\":\"Adds passed accountIds to a depositor's allow list. All addresses associated with the allowed accountIds will be able to signal intents on the user's deposit.\"},\"enableAllowlist()\":{\"notice\":\"Enables allow list for user, only users on the allow list will be able to signal intents on the user's deposit.\"},\"initialize(address,address)\":{\"notice\":\"Initialize Ramp with the addresses of the Processors\"},\"register(((string,string,string,string),bytes))\":{\"notice\":\"Registers a new account by pulling the profileId from the proof and assigning the account owner to the sender of the transaction.\"},\"registerAsOffRamper(((string,string,string,string),bytes))\":{\"notice\":\"Registers an account for off-ramping by pulling the multi-currency account id from the proof and assigning the account owner to the sender of the transaction.\"},\"removeAccountFromDenylist(bytes32)\":{\"notice\":\"Removes an accountId from a depositor's deny list.\"},\"removeAccountsFromAllowlist(bytes32[])\":{\"notice\":\"Removes an passed accountId's from allow list. If allow list is enabled only users on the allow list will be able to signal intents on the user's deposit.\"},\"setAccountRegistrationProcessor(address)\":{\"notice\":\"GOVERNANCE ONLY: Updates the account registration processor address used for validating and interpreting tls proofs.\"},\"setOffRamperRegistrationProcessor(address)\":{\"notice\":\"GOVERNANCE ONLY: Updates the off ramper registration processor address used for validating and interpreting tls proofs.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ramps/wise/WiseAccountRegistry.sol\":\"WiseAccountRegistry\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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/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/external/Bytes32ArrayUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.17;\\n\\n/**\\n * @title Bytes32ArrayUtils\\n * @author ZKP2P\\n *\\n * Fork of Set Protocol's AddressArrayUtils library adapted for usage with bytes32 arrays.\\n */\\nlibrary Bytes32ArrayUtils {\\n\\n uint256 constant internal MAX_INT = 2**256 - 1;\\n\\n /**\\n * Finds the index of the first occurrence of the given element.\\n * @param A The input array to search\\n * @param a The value to find\\n * @return Returns (index and isIn) for the first occurrence starting from index 0\\n */\\n function indexOf(bytes32[] memory A, bytes32 a) internal pure returns (uint256, bool) {\\n uint256 length = A.length;\\n for (uint256 i = 0; i < length; i++) {\\n if (A[i] == a) {\\n return (i, true);\\n }\\n }\\n return (MAX_INT, false);\\n }\\n\\n /**\\n * Returns true if the value is present in the list. Uses indexOf internally.\\n * @param A The input array to search\\n * @param a The value to find\\n * @return Returns isIn for the first occurrence starting from index 0\\n */\\n function contains(bytes32[] memory A, bytes32 a) internal pure returns (bool) {\\n (, bool isIn) = indexOf(A, a);\\n return isIn;\\n }\\n\\n /**\\n * Returns true if there are 2 elements that are the same in an array\\n * @param A The input array to search\\n * @return Returns boolean for the first occurrence of a duplicate\\n */\\n function hasDuplicate(bytes32[] memory A) internal pure returns(bool) {\\n require(A.length > 0, \\\"A is empty\\\");\\n\\n for (uint256 i = 0; i < A.length - 1; i++) {\\n bytes32 current = A[i];\\n for (uint256 j = i + 1; j < A.length; j++) {\\n if (current == A[j]) {\\n return true;\\n }\\n }\\n }\\n return false;\\n }\\n\\n /**\\n * @param A The input array to search\\n * @param a The bytes32 to remove\\n * @return Returns the array with the object removed.\\n */\\n function remove(bytes32[] memory A, bytes32 a)\\n internal\\n pure\\n returns (bytes32[] memory)\\n {\\n (uint256 index, bool isIn) = indexOf(A, a);\\n if (!isIn) {\\n revert(\\\"bytes32 not in array.\\\");\\n } else {\\n (bytes32[] memory _A,) = pop(A, index);\\n return _A;\\n }\\n }\\n\\n /**\\n * @param A The input array to search\\n * @param a The bytes32 to remove\\n */\\n function removeStorage(bytes32[] storage A, bytes32 a)\\n internal\\n {\\n (uint256 index, bool isIn) = indexOf(A, a);\\n if (!isIn) {\\n revert(\\\"bytes32 not in array.\\\");\\n } else {\\n uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here\\n if (index != lastIndex) { A[index] = A[lastIndex]; }\\n A.pop();\\n }\\n }\\n\\n /**\\n * Removes specified index from array\\n * @param A The input array to search\\n * @param index The index to remove\\n * @return Returns the new array and the removed entry\\n */\\n function pop(bytes32[] memory A, uint256 index)\\n internal\\n pure\\n returns (bytes32[] memory, bytes32)\\n {\\n uint256 length = A.length;\\n require(index < A.length, \\\"Index must be < A length\\\");\\n bytes32[] memory newBytes = new bytes32[](length - 1);\\n for (uint256 i = 0; i < index; i++) {\\n newBytes[i] = A[i];\\n }\\n for (uint256 j = index + 1; j < length; j++) {\\n newBytes[j - 1] = A[j];\\n }\\n return (newBytes, A[index]);\\n }\\n}\\n\",\"keccak256\":\"0x14d572deda126ff812eb5ab0eed33120e13cc568fd611a4a6bff652f3e8440a8\",\"license\":\"MIT\"},\"contracts/external/Uint256ArrayUtils.sol\":{\"content\":\"/*\\n Copyright 2020 Set Labs Inc.\\n\\n Licensed under the Apache License, Version 2.0 (the \\\"License\\\");\\n you may not use this file except in compliance with the License.\\n You may obtain a copy of the License at\\n\\n http://www.apache.org/licenses/LICENSE-2.0\\n\\n Unless required by applicable law or agreed to in writing, software\\n distributed under the License is distributed on an \\\"AS IS\\\" BASIS,\\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\\n See the License for the specific language governing permissions and\\n limitations under the License.\\n\\n SPDX-License-Identifier: Apache-2.0\\n*/\\n\\npragma solidity ^0.8.18;\\n\\n/**\\n * @title Uint256ArrayUtils\\n * @author Set Protocol\\n *\\n * Utility functions to handle Uint256 Arrays\\n */\\nlibrary Uint256ArrayUtils {\\n\\n uint256 constant internal MAX_INT = 2**256 - 1;\\n\\n /**\\n * Finds the index of the first occurrence of the given element.\\n * @param A The input array to search\\n * @param a The value to find\\n * @return Returns (index and isIn) for the first occurrence starting from index 0\\n */\\n function indexOf(uint256[] memory A, uint256 a) internal pure returns (uint256, bool) {\\n uint256 length = A.length;\\n for (uint256 i = 0; i < length; i++) {\\n if (A[i] == a) {\\n return (i, true);\\n }\\n }\\n return (MAX_INT, false);\\n }\\n\\n /**\\n * Returns the combination of the two arrays\\n * @param A The first array\\n * @param B The second array\\n * @return Returns A extended by B\\n */\\n function extend(uint256[] memory A, uint256[] memory B) internal pure returns (uint256[] memory) {\\n uint256 aLength = A.length;\\n uint256 bLength = B.length;\\n uint256[] memory newUints = new uint256[](aLength + bLength);\\n for (uint256 i = 0; i < aLength; i++) {\\n newUints[i] = A[i];\\n }\\n for (uint256 j = 0; j < bLength; j++) {\\n newUints[aLength + j] = B[j];\\n }\\n return newUints;\\n }\\n\\n /**\\n * @param A The input array to search\\n * @param a The bytes32 to remove\\n */\\n function removeStorage(uint256[] storage A, uint256 a)\\n internal\\n {\\n (uint256 index, bool isIn) = indexOf(A, a);\\n if (!isIn) {\\n revert(\\\"uint256 not in array.\\\");\\n } else {\\n uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here\\n if (index != lastIndex) { A[index] = A[lastIndex]; }\\n A.pop();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x102021415f8444ff563fc6d0082f39296f47c09ce73fb4cd642e700ac489eefe\",\"license\":\"Apache-2.0\"},\"contracts/ramps/wise/WiseAccountRegistry.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport { Bytes32ArrayUtils } from \\\"../../external/Bytes32ArrayUtils.sol\\\";\\nimport { Uint256ArrayUtils } from \\\"../../external/Uint256ArrayUtils.sol\\\";\\n\\nimport { IWiseAccountRegistrationProcessor } from \\\"./interfaces/IWiseAccountRegistrationProcessor.sol\\\";\\nimport { IWiseAccountRegistry } from \\\"./interfaces/IWiseAccountRegistry.sol\\\";\\nimport { IWiseOffRamperRegistrationProcessor } from \\\"./interfaces/IWiseOffRamperRegistrationProcessor.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract WiseAccountRegistry is IWiseAccountRegistry, Ownable {\\n using Bytes32ArrayUtils for bytes32[];\\n using Uint256ArrayUtils for uint256[];\\n\\n /* ============ Events ============ */\\n event AccountRegistered(address indexed accountOwner, bytes32 indexed accountId, bytes32 indexed wiseTagHash);\\n event OffRamperRegistered(address indexed accountOwner, bytes32 indexed accountId, bytes32 indexed offRampId);\\n\\n event UserAddedToDenylist(bytes32 listOwner, bytes32 deniedUser);\\n event UserRemovedFromDenylist(bytes32 listOwner, bytes32 approvedUser);\\n\\n event AllowlistEnabled(bytes32 listOwner);\\n event UserAddedToAllowlist(bytes32 indexed listOwner, bytes32 allowedUser);\\n event UserRemovedFromAllowlist(bytes32 indexed listOwner, bytes32 allowedUser);\\n\\n event NewAccountRegistrationProcessorSet(address registrationProcessor);\\n event NewOffRamperRegistrationProcessorSet(address registrationProcessor);\\n\\n /* ============ Structs ============ */\\n\\n struct DenyList {\\n bytes32[] deniedUsers; // Array of accountIds that are denied from taking depositors liquidity\\n mapping(bytes32 => bool) isDenied; // Mapping of accountId to boolean indicating if the user is denied\\n }\\n\\n struct AllowList {\\n bool isEnabled; // Boolean indicating if the allowlist is enabled\\n bytes32[] allowedUsers; // Array of accountIds that are allowed from taking depositors liquidity\\n mapping(bytes32 => bool) isAllowed; // Mapping of accountId to boolean indicating if the user is allowed\\n }\\n\\n /* ============ Modifiers ============ */\\n modifier onlyRegisteredUser() {\\n require(isRegisteredUser(msg.sender), \\\"Caller must be registered user\\\");\\n _;\\n }\\n\\n /* ============ State Variables ============ */\\n IWiseAccountRegistrationProcessor public accountRegistrationProcessor; // Address of Account registration processor contract\\n IWiseOffRamperRegistrationProcessor public offRamperRegistrationProcessor; // Address of Off-ramper registration processor contract\\n\\n bool public isInitialized; // Indicates if contract has been initialized\\n\\n mapping(address => AccountInfo) internal accounts; // Mapping of Ethereum accounts to their account information (IDs and deposits)\\n mapping(bytes32 => DenyList) internal denyList; // Mapping of accountId to denylist\\n mapping(bytes32 => AllowList) internal allowList; // Mapping of accountId to allow list\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _owner\\n )\\n Ownable()\\n {\\n transferOwnership(_owner);\\n }\\n\\n /* ============ External Functions ============ */\\n\\n /**\\n * @notice Initialize Ramp with the addresses of the Processors\\n *\\n * @param _accountRegistrationProcessor Account Registration processor address\\n * @param _offRamperRegistrationProcessor Off-ramper Registration processor address\\n */\\n function initialize(\\n IWiseAccountRegistrationProcessor _accountRegistrationProcessor,\\n IWiseOffRamperRegistrationProcessor _offRamperRegistrationProcessor\\n )\\n external\\n onlyOwner\\n {\\n require(!isInitialized, \\\"Already initialized\\\");\\n\\n accountRegistrationProcessor = _accountRegistrationProcessor;\\n offRamperRegistrationProcessor = _offRamperRegistrationProcessor;\\n\\n isInitialized = true;\\n }\\n\\n /**\\n * @notice Registers a new account by pulling the profileId from the proof and assigning the account owner to the\\n * sender of the transaction.\\n *\\n * @param _proof Registration proof consisting of unredacted data being notarized and a signature\\n */\\n function register(\\n IWiseAccountRegistrationProcessor.RegistrationProof calldata _proof\\n )\\n external\\n {\\n require(accounts[msg.sender].accountId == bytes32(0), \\\"Account already associated with accountId\\\");\\n (\\n bytes32 accountId,\\n bytes32 wiseTagHash\\n ) = _verifyRegistrationProof(_proof);\\n\\n accounts[msg.sender].accountId = accountId;\\n accounts[msg.sender].wiseTagHash = wiseTagHash;\\n\\n emit AccountRegistered(msg.sender, accountId, wiseTagHash);\\n }\\n\\n /**\\n * @notice Registers an account for off-ramping by pulling the multi-currency account id from the proof and assigning\\n * the account owner to the sender of the transaction.\\n *\\n * @param _proof Registration proof consisting of unredacted data being notarized and a signature\\n */\\n function registerAsOffRamper(\\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof calldata _proof\\n )\\n external\\n onlyRegisteredUser\\n {\\n require(accounts[msg.sender].offRampId == bytes32(0), \\\"Account already associated with offRampId\\\");\\n (\\n bytes32 accountId,\\n bytes32 offRampId\\n ) = _verifyOffRamperRegistrationProof(_proof);\\n\\n accounts[msg.sender].accountId = accountId;\\n accounts[msg.sender].offRampId = offRampId;\\n\\n emit OffRamperRegistered(msg.sender, accountId, offRampId);\\n }\\n\\n /**\\n * @notice Adds an accountId to a depositor's deny list. If an address associated with the banned accountId attempts to\\n * signal an intent on the user's deposit they will be denied.\\n *\\n * @param _deniedUser accountId being banned\\n */\\n function addAccountToDenylist(bytes32 _deniedUser) external onlyRegisteredUser {\\n bytes32 denyingUser = accounts[msg.sender].accountId;\\n\\n require(!denyList[denyingUser].isDenied[_deniedUser], \\\"User already on denylist\\\");\\n\\n denyList[denyingUser].isDenied[_deniedUser] = true;\\n denyList[denyingUser].deniedUsers.push(_deniedUser);\\n\\n emit UserAddedToDenylist(denyingUser, _deniedUser);\\n }\\n\\n /**\\n * @notice Removes an accountId from a depositor's deny list.\\n *\\n * @param _approvedUser accountId being approved\\n */\\n function removeAccountFromDenylist(bytes32 _approvedUser) external onlyRegisteredUser {\\n bytes32 approvingUser = accounts[msg.sender].accountId;\\n\\n require(denyList[approvingUser].isDenied[_approvedUser], \\\"User not on denylist\\\");\\n\\n denyList[approvingUser].isDenied[_approvedUser] = false;\\n denyList[approvingUser].deniedUsers.removeStorage(_approvedUser);\\n\\n emit UserRemovedFromDenylist(approvingUser, _approvedUser);\\n }\\n\\n /**\\n * @notice Enables allow list for user, only users on the allow list will be able to signal intents on the user's deposit.\\n */\\n function enableAllowlist() external onlyRegisteredUser {\\n bytes32 allowingUser = accounts[msg.sender].accountId;\\n\\n require(!allowList[allowingUser].isEnabled, \\\"Allow list already enabled\\\");\\n\\n allowList[allowingUser].isEnabled = true;\\n\\n emit AllowlistEnabled(allowingUser);\\n }\\n\\n /**\\n * @notice Adds passed accountIds to a depositor's allow list. All addresses associated with the allowed accountIds will\\n * be able to signal intents on the user's deposit.\\n *\\n * @param _allowedUsers List of accountIds allowed to signal intents on the user's deposit\\n */\\n function addAccountsToAllowlist(bytes32[] memory _allowedUsers) external onlyRegisteredUser {\\n bytes32 allowingUser = accounts[msg.sender].accountId;\\n\\n for(uint256 i = 0; i < _allowedUsers.length; i++) {\\n bytes32 allowedUser = _allowedUsers[i];\\n\\n require(!allowList[allowingUser].isAllowed[allowedUser], \\\"User already on allowlist\\\");\\n\\n allowList[allowingUser].isAllowed[allowedUser] = true;\\n allowList[allowingUser].allowedUsers.push(allowedUser);\\n\\n emit UserAddedToAllowlist(allowingUser, allowedUser);\\n }\\n }\\n\\n /**\\n * @notice Removes an passed accountId's from allow list. If allow list is enabled only users on the allow list will be\\n * able to signal intents on the user's deposit.\\n *\\n * @param _disallowedUsers List of accountIds being approved\\n */\\n function removeAccountsFromAllowlist(bytes32[] memory _disallowedUsers) external onlyRegisteredUser {\\n bytes32 disallowingUser = accounts[msg.sender].accountId;\\n\\n for(uint256 i = 0; i < _disallowedUsers.length; i++) {\\n bytes32 disallowedUser = _disallowedUsers[i];\\n\\n require(allowList[disallowingUser].isAllowed[disallowedUser], \\\"User not on allowlist\\\");\\n\\n allowList[disallowingUser].isAllowed[disallowedUser] = false;\\n allowList[disallowingUser].allowedUsers.removeStorage(disallowedUser);\\n\\n emit UserRemovedFromAllowlist(disallowingUser, disallowedUser);\\n }\\n }\\n\\n /* ============ Governance Functions ============ */\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the account registration processor address used for validating and interpreting tls proofs.\\n *\\n * @param _registrationProcessor New registration proccesor address\\n */\\n function setAccountRegistrationProcessor(IWiseAccountRegistrationProcessor _registrationProcessor) external onlyOwner {\\n accountRegistrationProcessor = _registrationProcessor;\\n emit NewAccountRegistrationProcessorSet(address(_registrationProcessor));\\n }\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the off ramper registration processor address used for validating and interpreting tls proofs.\\n *\\n * @param _registrationProcessor New registration proccesor address\\n */\\n function setOffRamperRegistrationProcessor(IWiseOffRamperRegistrationProcessor _registrationProcessor) external onlyOwner {\\n offRamperRegistrationProcessor = _registrationProcessor;\\n emit NewOffRamperRegistrationProcessorSet(address(_registrationProcessor));\\n }\\n\\n /* ============ External View Functions ============ */\\n\\n function getAccountInfo(address _account) external view returns (AccountInfo memory) {\\n return accounts[_account];\\n }\\n\\n function getAccountId(address _account) public view returns (bytes32) {\\n return accounts[_account].accountId;\\n }\\n\\n function isRegisteredUser(address _account) public view returns (bool) {\\n return getAccountId(_account) != bytes32(0);\\n }\\n\\n function getDeniedUsers(address _account) external view returns (bytes32[] memory) {\\n return denyList[getAccountId(_account)].deniedUsers;\\n }\\n\\n function isDeniedUser(address _account, bytes32 _deniedUser) external view returns (bool) {\\n return denyList[getAccountId(_account)].isDenied[_deniedUser];\\n }\\n\\n function isAllowlistEnabled(address _account) external view returns (bool) {\\n return allowList[getAccountId(_account)].isEnabled;\\n }\\n\\n function getAllowedUsers(address _account) external view returns (bytes32[] memory) {\\n return allowList[getAccountId(_account)].allowedUsers;\\n }\\n\\n function isAllowedUser(address _account, bytes32 _allowedUser) external view returns (bool) {\\n bytes32 allowingUser = getAccountId(_account);\\n\\n // Deny list overrides, if user on deny list then they are not allowed\\n if(denyList[allowingUser].isDenied[_allowedUser]) { return false; }\\n\\n // Check if allow list is enabled, if so return status of user, else return true\\n return allowList[allowingUser].isEnabled ? allowList[allowingUser].isAllowed[_allowedUser] : true;\\n }\\n \\n /* ============ Internal Functions ============ */\\n\\n /**\\n * @notice Validate the user has an Wise account, we do not nullify this email since it can be reused to register under\\n * different addresses.\\n */\\n function _verifyRegistrationProof(\\n IWiseAccountRegistrationProcessor.RegistrationProof calldata _proof\\n )\\n internal\\n returns(bytes32 accountId, bytes32 wiseTagHash)\\n {\\n (\\n accountId,\\n wiseTagHash\\n ) = accountRegistrationProcessor.processAccountProof(_proof);\\n }\\n\\n /**\\n * @notice Validate the user has an Wise account, we do not nullify this email since it can be reused to register under\\n * different addresses.\\n */\\n function _verifyOffRamperRegistrationProof(\\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof calldata _proof\\n )\\n internal\\n returns(bytes32 accountId, bytes32 offRampId)\\n {\\n (\\n accountId,\\n offRampId\\n ) = offRamperRegistrationProcessor.processOffRamperProof(_proof);\\n\\n require(accountId == accounts[msg.sender].accountId, \\\"OnRampId does not match\\\");\\n }\\n}\\n\",\"keccak256\":\"0xf323d8b07ee52e9c402129b97efe7a1866e99ed2d92b094390b3ed33ac1d6a72\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseAccountRegistrationProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseAccountRegistrationProcessor {\\n\\n struct RegistrationData {\\n string endpoint;\\n string host;\\n string profileId;\\n string wiseTagHash;\\n }\\n\\n struct RegistrationProof {\\n RegistrationData public_values;\\n bytes proof;\\n }\\n\\n function processAccountProof(\\n RegistrationProof calldata _proof\\n )\\n external\\n returns (bytes32, bytes32);\\n}\\n\",\"keccak256\":\"0x99082f42d3232cf43f2799492721369f11636b8be18cb4486f037dca2e894584\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseAccountRegistry.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseAccountRegistry {\\n\\n // Each Account is tied to a Wise ID and is represented by an Ethereum address.\\n struct AccountInfo {\\n bytes32 accountId; // User's Wise account ID\\n bytes32 offRampId; // Multi-currency account ID to receive funds\\n bytes32 wiseTagHash; // Hash of user's wise tag account stored on register. Used to verify offramper's wise tag\\n }\\n\\n function getAccountInfo(address _account) external view returns (AccountInfo memory);\\n function getAccountId(address _account) external view returns (bytes32);\\n\\n function isRegisteredUser(address _account) external view returns (bool);\\n \\n function isAllowedUser(address _account, bytes32 _deniedUser) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xfaf30dc7e7dd1a0bce25c0188059b17bde3929fb473570bc8860a82ae97c5b35\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseOffRamperRegistrationProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseOffRamperRegistrationProcessor {\\n\\n struct OffRamperRegistrationData {\\n string endpoint;\\n string host;\\n string profileId;\\n string mcAccountId;\\n }\\n\\n struct OffRamperRegistrationProof {\\n OffRamperRegistrationData public_values;\\n bytes proof;\\n }\\n\\n function processOffRamperProof(\\n OffRamperRegistrationProof calldata _proof\\n )\\n external\\n returns (bytes32, bytes32);\\n}\\n\",\"keccak256\":\"0x6461b64625b383ad3eb4c526d937413b23157f50262504c02187ed0556b036fb\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50604051620018df380380620018df833981016040819052620000349162000182565b6200003f3362000051565b6200004a81620000a1565b50620001b4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620000ab62000124565b6001600160a01b038116620001165760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001218162000051565b50565b6000546001600160a01b03163314620001805760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200010d565b565b6000602082840312156200019557600080fd5b81516001600160a01b0381168114620001ad57600080fd5b9392505050565b61171b80620001c46000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c8063715018a6116100c3578063c6a2aac81161007c578063c6a2aac814610356578063d88452451461035e578063e0b490f714610371578063e39ca3b414610392578063f2fde38b146103a5578063fbf15b1f146103b857600080fd5b8063715018a61461027e5780637b510fe8146102865780638da5cb5b1461030c5780639b357b5a1461031d578063b14fac2e14610330578063c3eb86811461034357600080fd5b80633056eb28116101155780633056eb28146101fe57806338e4bef614610211578063392e53cd146102245780634595bba014610238578063485cc95514610258578063605958f41461026b57600080fd5b80630876dda31461015d578063148172da1461018d5780631acd84d8146101a25780631d16612e146101c55780631e48fe6b146101d85780631f5bdf5d146101eb575b600080fd5b600154610170906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101a061019b36600461129b565b6103cb565b005b6101b56101b03660046112c9565b6104f2565b6040519015158152602001610184565b6101a06101d336600461130d565b610578565b6101a06101e6366004611358565b61063f565b6101b56101f9366004611416565b61078e565b6101a061020c366004611416565b6107a2565b6101b561021f366004611416565b6107ff565b6002546101b590600160a01b900460ff1681565b61024b610246366004611416565b610828565b604051610184919061143a565b6101a061026636600461147e565b61089e565b600254610170906001600160a01b031681565b6101a0610931565b6102ea610294366004611416565b6040805160608082018352600080835260208084018290529284018190526001600160a01b0394909416845260038252928290208251938401835280548452600181015491840191909152600201549082015290565b6040805182518152602080840151908201529181015190820152606001610184565b6000546001600160a01b0316610170565b6101a061032b36600461129b565b610945565b6101a061033e36600461130d565b610a44565b6101a0610351366004611416565b610b33565b6101a0610b89565b6101a061036c366004611358565b610c68565b61038461037f366004611416565b610dc3565b604051908152602001610184565b61024b6103a0366004611416565b610dde565b6101a06103b3366004611416565b610e52565b6101b56103c63660046112c9565b610ecb565b6103d43361078e565b6103f95760405162461bcd60e51b81526004016103f0906114b7565b60405180910390fd5b33600090815260036020908152604080832054808452600483528184208585526001019092529091205460ff16156104735760405162461bcd60e51b815260206004820152601860248201527f5573657220616c7265616479206f6e2064656e796c697374000000000000000060448201526064016103f0565b600081815260046020818152604080842086855260018181018452828620805460ff191682179055938352805493840181558452922001839055517f976c693d56f27ba17d902bda80c4fa0416b773fbf268bcb0ee71689234d769ee906104e69083908590918252602082015260400190565b60405180910390a15050565b6000806104fe84610dc3565b600081815260046020908152604080832087845260010190915290205490915060ff1615610530576000915050610572565b60008181526005602052604090205460ff1661054d57600161056e565b600081815260056020908152604080832086845260020190915290205460ff165b9150505b92915050565b33600090815260036020526040902054156105e75760405162461bcd60e51b815260206004820152602960248201527f4163636f756e7420616c7265616479206173736f6369617465642077697468206044820152681858d8dbdd5b9d125960ba1b60648201526084016103f0565b6000806105f383610f06565b3360008181526003602052604080822085815560020184905551939550919350839285927fcc65223c6e9df339af3ea6f6f0bf09fa478060d7c745142bdccb626ef62c79e291a4505050565b6106483361078e565b6106645760405162461bcd60e51b81526004016103f0906114b7565b33600090815260036020526040812054905b8251811015610789576000838281518110610693576106936114ee565b6020908102919091018101516000858152600583526040808220838352600201909352919091205490915060ff166107055760405162461bcd60e51b8152602060048201526015602482015274155cd95c881b9bdd081bdb88185b1b1bdddb1a5cdd605a1b60448201526064016103f0565b6000838152600560208181526040808420858552600281018352908420805460ff19169055928690525261073c9060010182610f87565b827fe87ba7050133e8b4c8b879f99b3276368eaca3b81f4ea415d9528843a15d8c638260405161076e91815260200190565b60405180910390a250806107818161151a565b915050610676565b505050565b60008061079a83610dc3565b141592915050565b6107aa6110af565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527ffd4e734c9a89ace3649766f5233487313285fe97ca577c2602beda889ef46dd3906020015b60405180910390a150565b60006005600061080e84610dc3565b815260208101919091526040016000205460ff1692915050565b60606004600061083784610dc3565b815260200190815260200160002060000180548060200260200160405190810160405280929190818152602001828054801561089257602002820191906000526020600020905b81548152602001906001019080831161087e575b50505050509050919050565b6108a66110af565b600254600160a01b900460ff16156108f65760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016103f0565b600180546001600160a01b039384166001600160a01b0319909116179055600280546001600160a81b0319169190921617600160a01b179055565b6109396110af565b6109436000611109565b565b61094e3361078e565b61096a5760405162461bcd60e51b81526004016103f0906114b7565b33600090815260036020908152604080832054808452600483528184208585526001019092529091205460ff166109da5760405162461bcd60e51b8152602060048201526014602482015273155cd95c881b9bdd081bdb8819195b9e5b1a5cdd60621b60448201526064016103f0565b6000818152600460208181526040808420868552600181018352908420805460ff191690559284905252610a0e9083610f87565b60408051828152602081018490527f8935205b1b382095d2d95efbb36f81a11a34c548d45af26adc1a02d2f2bb546f91016104e6565b610a4d3361078e565b610a695760405162461bcd60e51b81526004016103f0906114b7565b3360009081526003602052604090206001015415610adb5760405162461bcd60e51b815260206004820152602960248201527f4163636f756e7420616c7265616479206173736f6369617465642077697468206044820152681bd99994985b5c125960ba1b60648201526084016103f0565b600080610ae783611159565b3360008181526003602052604080822085815560010184905551939550919350839285927f1145ead7f8f95549bd8948731c7e50cda0ef6a0bba6867ee9e383633c2de4c2091a4505050565b610b3b6110af565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f32bce9e8b6bd060cc566144f14693fad172bd139e984b38c7c83c6d29ef1ad48906020016107f4565b610b923361078e565b610bae5760405162461bcd60e51b81526004016103f0906114b7565b3360009081526003602090815260408083205480845260059092529091205460ff1615610c1d5760405162461bcd60e51b815260206004820152601a60248201527f416c6c6f77206c69737420616c726561647920656e61626c656400000000000060448201526064016103f0565b60008181526005602052604090819020805460ff19166001179055517f08df0a71ea3e5565a2138936ed06eaba47996a3ccfde2dae1f3edd1164e299d7906107f49083815260200190565b610c713361078e565b610c8d5760405162461bcd60e51b81526004016103f0906114b7565b33600090815260036020526040812054905b8251811015610789576000838281518110610cbc57610cbc6114ee565b6020908102919091018101516000858152600583526040808220838352600201909352919091205490915060ff1615610d375760405162461bcd60e51b815260206004820152601960248201527f5573657220616c7265616479206f6e20616c6c6f776c6973740000000000000060448201526064016103f0565b6000838152600560208181526040808420858552600281018352818520805460ff1916600190811790915593835283018054938401815584529220018290555183907f857ce673abc5a303fa8303102f12b42079aa85b97bca15b56428764dd1dec4d290610da89084815260200190565b60405180910390a25080610dbb8161151a565b915050610c9f565b6001600160a01b031660009081526003602052604090205490565b606060056000610ded84610dc3565b8152602001908152602001600020600101805480602002602001604051908101604052809291908181526020018280548015610892576020028201919060005260206000209081548152602001906001019080831161087e5750505050509050919050565b610e5a6110af565b6001600160a01b038116610ebf5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103f0565b610ec881611109565b50565b600060046000610eda85610dc3565b81526020808201929092526040908101600090812085825260010190925290205460ff16905092915050565b600154604051633ac2459960e11b815260009182916001600160a01b03909116906375848b3290610f3b908690600401611685565b60408051808303816000875af1158015610f59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7d9190611698565b9094909350915050565b600080610fe384805480602002602001604051908101604052809291908181526020018280548015610fd857602002820191906000526020600020905b815481526020019060010190808311610fc4575b505050505084611238565b915091508061102c5760405162461bcd60e51b8152602060048201526015602482015274313cba32b99999103737ba1034b71030b93930bc9760591b60448201526064016103f0565b835460009061103d906001906116bc565b905080831461108257848181548110611058576110586114ee565b9060005260206000200154858481548110611075576110756114ee565b6000918252602090912001555b84805480611092576110926116cf565b600190038181906000526020600020016000905590555050505050565b6000546001600160a01b031633146109435760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103f0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60025460405163508c209360e01b815260009182916001600160a01b039091169063508c20939061118e908690600401611685565b60408051808303816000875af11580156111ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d09190611698565b33600090815260036020526040902054919350915082146112335760405162461bcd60e51b815260206004820152601760248201527f4f6e52616d70496420646f6573206e6f74206d6174636800000000000000000060448201526064016103f0565b915091565b81516000908190815b81811015611288578486828151811061125c5761125c6114ee565b602002602001015103611276579250600191506112949050565b806112808161151a565b915050611241565b50600019600092509250505b9250929050565b6000602082840312156112ad57600080fd5b5035919050565b6001600160a01b0381168114610ec857600080fd5b600080604083850312156112dc57600080fd5b82356112e7816112b4565b946020939093013593505050565b60006040828403121561130757600080fd5b50919050565b60006020828403121561131f57600080fd5b813567ffffffffffffffff81111561133657600080fd5b61056e848285016112f5565b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561136b57600080fd5b823567ffffffffffffffff8082111561138357600080fd5b818501915085601f83011261139757600080fd5b8135818111156113a9576113a9611342565b8060051b604051601f19603f830116810181811085821117156113ce576113ce611342565b6040529182528482019250838101850191888311156113ec57600080fd5b938501935b8285101561140a578435845293850193928501926113f1565b98975050505050505050565b60006020828403121561142857600080fd5b8135611433816112b4565b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561147257835183529284019291840191600101611456565b50909695505050505050565b6000806040838503121561149157600080fd5b823561149c816112b4565b915060208301356114ac816112b4565b809150509250929050565b6020808252601e908201527f43616c6c6572206d757374206265207265676973746572656420757365720000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161152c5761152c611504565b5060010190565b6000808335601e1984360301811261154a57600080fd5b830160208101925035905067ffffffffffffffff81111561156a57600080fd5b80360382131561129457600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60008135607e198336030181126115b857600080fd5b6040845282016115c88180611533565b608060408701526115dd60c087018284611579565b9150506115ed6020830183611533565b603f1980888503016060890152611605848385611579565b93506116146040860186611533565b935091508088850301608089015261162d848484611579565b935061163c6060860186611533565b95509250808885030160a08901525050611657828483611579565b925050506116686020840184611533565b858303602087015261167b838284611579565b9695505050505050565b60208152600061143360208301846115a2565b600080604083850312156116ab57600080fd5b505080516020909101519092909150565b8181038181111561057257610572611504565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220ada3d610464f0149fd541be85c3984d9ecc3760d2292f8a150088b429a5d25c664736f6c63430008120033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101585760003560e01c8063715018a6116100c3578063c6a2aac81161007c578063c6a2aac814610356578063d88452451461035e578063e0b490f714610371578063e39ca3b414610392578063f2fde38b146103a5578063fbf15b1f146103b857600080fd5b8063715018a61461027e5780637b510fe8146102865780638da5cb5b1461030c5780639b357b5a1461031d578063b14fac2e14610330578063c3eb86811461034357600080fd5b80633056eb28116101155780633056eb28146101fe57806338e4bef614610211578063392e53cd146102245780634595bba014610238578063485cc95514610258578063605958f41461026b57600080fd5b80630876dda31461015d578063148172da1461018d5780631acd84d8146101a25780631d16612e146101c55780631e48fe6b146101d85780631f5bdf5d146101eb575b600080fd5b600154610170906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101a061019b36600461129b565b6103cb565b005b6101b56101b03660046112c9565b6104f2565b6040519015158152602001610184565b6101a06101d336600461130d565b610578565b6101a06101e6366004611358565b61063f565b6101b56101f9366004611416565b61078e565b6101a061020c366004611416565b6107a2565b6101b561021f366004611416565b6107ff565b6002546101b590600160a01b900460ff1681565b61024b610246366004611416565b610828565b604051610184919061143a565b6101a061026636600461147e565b61089e565b600254610170906001600160a01b031681565b6101a0610931565b6102ea610294366004611416565b6040805160608082018352600080835260208084018290529284018190526001600160a01b0394909416845260038252928290208251938401835280548452600181015491840191909152600201549082015290565b6040805182518152602080840151908201529181015190820152606001610184565b6000546001600160a01b0316610170565b6101a061032b36600461129b565b610945565b6101a061033e36600461130d565b610a44565b6101a0610351366004611416565b610b33565b6101a0610b89565b6101a061036c366004611358565b610c68565b61038461037f366004611416565b610dc3565b604051908152602001610184565b61024b6103a0366004611416565b610dde565b6101a06103b3366004611416565b610e52565b6101b56103c63660046112c9565b610ecb565b6103d43361078e565b6103f95760405162461bcd60e51b81526004016103f0906114b7565b60405180910390fd5b33600090815260036020908152604080832054808452600483528184208585526001019092529091205460ff16156104735760405162461bcd60e51b815260206004820152601860248201527f5573657220616c7265616479206f6e2064656e796c697374000000000000000060448201526064016103f0565b600081815260046020818152604080842086855260018181018452828620805460ff191682179055938352805493840181558452922001839055517f976c693d56f27ba17d902bda80c4fa0416b773fbf268bcb0ee71689234d769ee906104e69083908590918252602082015260400190565b60405180910390a15050565b6000806104fe84610dc3565b600081815260046020908152604080832087845260010190915290205490915060ff1615610530576000915050610572565b60008181526005602052604090205460ff1661054d57600161056e565b600081815260056020908152604080832086845260020190915290205460ff165b9150505b92915050565b33600090815260036020526040902054156105e75760405162461bcd60e51b815260206004820152602960248201527f4163636f756e7420616c7265616479206173736f6369617465642077697468206044820152681858d8dbdd5b9d125960ba1b60648201526084016103f0565b6000806105f383610f06565b3360008181526003602052604080822085815560020184905551939550919350839285927fcc65223c6e9df339af3ea6f6f0bf09fa478060d7c745142bdccb626ef62c79e291a4505050565b6106483361078e565b6106645760405162461bcd60e51b81526004016103f0906114b7565b33600090815260036020526040812054905b8251811015610789576000838281518110610693576106936114ee565b6020908102919091018101516000858152600583526040808220838352600201909352919091205490915060ff166107055760405162461bcd60e51b8152602060048201526015602482015274155cd95c881b9bdd081bdb88185b1b1bdddb1a5cdd605a1b60448201526064016103f0565b6000838152600560208181526040808420858552600281018352908420805460ff19169055928690525261073c9060010182610f87565b827fe87ba7050133e8b4c8b879f99b3276368eaca3b81f4ea415d9528843a15d8c638260405161076e91815260200190565b60405180910390a250806107818161151a565b915050610676565b505050565b60008061079a83610dc3565b141592915050565b6107aa6110af565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527ffd4e734c9a89ace3649766f5233487313285fe97ca577c2602beda889ef46dd3906020015b60405180910390a150565b60006005600061080e84610dc3565b815260208101919091526040016000205460ff1692915050565b60606004600061083784610dc3565b815260200190815260200160002060000180548060200260200160405190810160405280929190818152602001828054801561089257602002820191906000526020600020905b81548152602001906001019080831161087e575b50505050509050919050565b6108a66110af565b600254600160a01b900460ff16156108f65760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016103f0565b600180546001600160a01b039384166001600160a01b0319909116179055600280546001600160a81b0319169190921617600160a01b179055565b6109396110af565b6109436000611109565b565b61094e3361078e565b61096a5760405162461bcd60e51b81526004016103f0906114b7565b33600090815260036020908152604080832054808452600483528184208585526001019092529091205460ff166109da5760405162461bcd60e51b8152602060048201526014602482015273155cd95c881b9bdd081bdb8819195b9e5b1a5cdd60621b60448201526064016103f0565b6000818152600460208181526040808420868552600181018352908420805460ff191690559284905252610a0e9083610f87565b60408051828152602081018490527f8935205b1b382095d2d95efbb36f81a11a34c548d45af26adc1a02d2f2bb546f91016104e6565b610a4d3361078e565b610a695760405162461bcd60e51b81526004016103f0906114b7565b3360009081526003602052604090206001015415610adb5760405162461bcd60e51b815260206004820152602960248201527f4163636f756e7420616c7265616479206173736f6369617465642077697468206044820152681bd99994985b5c125960ba1b60648201526084016103f0565b600080610ae783611159565b3360008181526003602052604080822085815560010184905551939550919350839285927f1145ead7f8f95549bd8948731c7e50cda0ef6a0bba6867ee9e383633c2de4c2091a4505050565b610b3b6110af565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f32bce9e8b6bd060cc566144f14693fad172bd139e984b38c7c83c6d29ef1ad48906020016107f4565b610b923361078e565b610bae5760405162461bcd60e51b81526004016103f0906114b7565b3360009081526003602090815260408083205480845260059092529091205460ff1615610c1d5760405162461bcd60e51b815260206004820152601a60248201527f416c6c6f77206c69737420616c726561647920656e61626c656400000000000060448201526064016103f0565b60008181526005602052604090819020805460ff19166001179055517f08df0a71ea3e5565a2138936ed06eaba47996a3ccfde2dae1f3edd1164e299d7906107f49083815260200190565b610c713361078e565b610c8d5760405162461bcd60e51b81526004016103f0906114b7565b33600090815260036020526040812054905b8251811015610789576000838281518110610cbc57610cbc6114ee565b6020908102919091018101516000858152600583526040808220838352600201909352919091205490915060ff1615610d375760405162461bcd60e51b815260206004820152601960248201527f5573657220616c7265616479206f6e20616c6c6f776c6973740000000000000060448201526064016103f0565b6000838152600560208181526040808420858552600281018352818520805460ff1916600190811790915593835283018054938401815584529220018290555183907f857ce673abc5a303fa8303102f12b42079aa85b97bca15b56428764dd1dec4d290610da89084815260200190565b60405180910390a25080610dbb8161151a565b915050610c9f565b6001600160a01b031660009081526003602052604090205490565b606060056000610ded84610dc3565b8152602001908152602001600020600101805480602002602001604051908101604052809291908181526020018280548015610892576020028201919060005260206000209081548152602001906001019080831161087e5750505050509050919050565b610e5a6110af565b6001600160a01b038116610ebf5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103f0565b610ec881611109565b50565b600060046000610eda85610dc3565b81526020808201929092526040908101600090812085825260010190925290205460ff16905092915050565b600154604051633ac2459960e11b815260009182916001600160a01b03909116906375848b3290610f3b908690600401611685565b60408051808303816000875af1158015610f59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7d9190611698565b9094909350915050565b600080610fe384805480602002602001604051908101604052809291908181526020018280548015610fd857602002820191906000526020600020905b815481526020019060010190808311610fc4575b505050505084611238565b915091508061102c5760405162461bcd60e51b8152602060048201526015602482015274313cba32b99999103737ba1034b71030b93930bc9760591b60448201526064016103f0565b835460009061103d906001906116bc565b905080831461108257848181548110611058576110586114ee565b9060005260206000200154858481548110611075576110756114ee565b6000918252602090912001555b84805480611092576110926116cf565b600190038181906000526020600020016000905590555050505050565b6000546001600160a01b031633146109435760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103f0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60025460405163508c209360e01b815260009182916001600160a01b039091169063508c20939061118e908690600401611685565b60408051808303816000875af11580156111ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d09190611698565b33600090815260036020526040902054919350915082146112335760405162461bcd60e51b815260206004820152601760248201527f4f6e52616d70496420646f6573206e6f74206d6174636800000000000000000060448201526064016103f0565b915091565b81516000908190815b81811015611288578486828151811061125c5761125c6114ee565b602002602001015103611276579250600191506112949050565b806112808161151a565b915050611241565b50600019600092509250505b9250929050565b6000602082840312156112ad57600080fd5b5035919050565b6001600160a01b0381168114610ec857600080fd5b600080604083850312156112dc57600080fd5b82356112e7816112b4565b946020939093013593505050565b60006040828403121561130757600080fd5b50919050565b60006020828403121561131f57600080fd5b813567ffffffffffffffff81111561133657600080fd5b61056e848285016112f5565b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561136b57600080fd5b823567ffffffffffffffff8082111561138357600080fd5b818501915085601f83011261139757600080fd5b8135818111156113a9576113a9611342565b8060051b604051601f19603f830116810181811085821117156113ce576113ce611342565b6040529182528482019250838101850191888311156113ec57600080fd5b938501935b8285101561140a578435845293850193928501926113f1565b98975050505050505050565b60006020828403121561142857600080fd5b8135611433816112b4565b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561147257835183529284019291840191600101611456565b50909695505050505050565b6000806040838503121561149157600080fd5b823561149c816112b4565b915060208301356114ac816112b4565b809150509250929050565b6020808252601e908201527f43616c6c6572206d757374206265207265676973746572656420757365720000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161152c5761152c611504565b5060010190565b6000808335601e1984360301811261154a57600080fd5b830160208101925035905067ffffffffffffffff81111561156a57600080fd5b80360382131561129457600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60008135607e198336030181126115b857600080fd5b6040845282016115c88180611533565b608060408701526115dd60c087018284611579565b9150506115ed6020830183611533565b603f1980888503016060890152611605848385611579565b93506116146040860186611533565b935091508088850301608089015261162d848484611579565b935061163c6060860186611533565b95509250808885030160a08901525050611657828483611579565b925050506116686020840184611533565b858303602087015261167b838284611579565b9695505050505050565b60208152600061143360208301846115a2565b600080604083850312156116ab57600080fd5b505080516020909101519092909150565b8181038181111561057257610572611504565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220ada3d610464f0149fd541be85c3984d9ecc3760d2292f8a150088b429a5d25c664736f6c63430008120033", + "solcInputHash": "0de631e329f560f49e3d6a21d19a30cc", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"accountOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"accountId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"wiseTagHash\",\"type\":\"bytes32\"}],\"name\":\"AccountRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"listOwner\",\"type\":\"bytes32\"}],\"name\":\"AllowlistEnabled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"registrationProcessor\",\"type\":\"address\"}],\"name\":\"NewAccountRegistrationProcessorSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"registrationProcessor\",\"type\":\"address\"}],\"name\":\"NewOffRamperRegistrationProcessorSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"accountOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"accountId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"offRampId\",\"type\":\"bytes32\"}],\"name\":\"OffRamperRegistered\",\"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\":\"bytes32\",\"name\":\"listOwner\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"allowedUser\",\"type\":\"bytes32\"}],\"name\":\"UserAddedToAllowlist\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"listOwner\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"deniedUser\",\"type\":\"bytes32\"}],\"name\":\"UserAddedToDenylist\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"listOwner\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"allowedUser\",\"type\":\"bytes32\"}],\"name\":\"UserRemovedFromAllowlist\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"listOwner\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"approvedUser\",\"type\":\"bytes32\"}],\"name\":\"UserRemovedFromDenylist\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountRegistrationProcessor\",\"outputs\":[{\"internalType\":\"contract IWiseAccountRegistrationProcessor\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_deniedUser\",\"type\":\"bytes32\"}],\"name\":\"addAccountToDenylist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"_allowedUsers\",\"type\":\"bytes32[]\"}],\"name\":\"addAccountsToAllowlist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"enableAllowlist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getAccountId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getAccountInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"accountId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"offRampId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"wiseTagHash\",\"type\":\"bytes32\"}],\"internalType\":\"struct IWiseAccountRegistry.AccountInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getAllowedUsers\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getDeniedUsers\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWiseAccountRegistrationProcessor\",\"name\":\"_accountRegistrationProcessor\",\"type\":\"address\"},{\"internalType\":\"contract IWiseOffRamperRegistrationProcessor\",\"name\":\"_offRamperRegistrationProcessor\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_allowedUser\",\"type\":\"bytes32\"}],\"name\":\"isAllowedUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"isAllowlistEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_deniedUser\",\"type\":\"bytes32\"}],\"name\":\"isDeniedUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"isRegisteredUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offRamperRegistrationProcessor\",\"outputs\":[{\"internalType\":\"contract IWiseOffRamperRegistrationProcessor\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"profileId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"wiseTagHash\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"userAddress\",\"type\":\"address\"}],\"internalType\":\"struct IWiseAccountRegistrationProcessor.RegistrationData\",\"name\":\"public_values\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"internalType\":\"struct IWiseAccountRegistrationProcessor.RegistrationProof\",\"name\":\"_proof\",\"type\":\"tuple\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"profileId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"mcAccountId\",\"type\":\"string\"}],\"internalType\":\"struct IWiseOffRamperRegistrationProcessor.OffRamperRegistrationData\",\"name\":\"public_values\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"internalType\":\"struct IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof\",\"name\":\"_proof\",\"type\":\"tuple\"}],\"name\":\"registerAsOffRamper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_approvedUser\",\"type\":\"bytes32\"}],\"name\":\"removeAccountFromDenylist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"_disallowedUsers\",\"type\":\"bytes32[]\"}],\"name\":\"removeAccountsFromAllowlist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWiseAccountRegistrationProcessor\",\"name\":\"_registrationProcessor\",\"type\":\"address\"}],\"name\":\"setAccountRegistrationProcessor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWiseOffRamperRegistrationProcessor\",\"name\":\"_registrationProcessor\",\"type\":\"address\"}],\"name\":\"setOffRamperRegistrationProcessor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addAccountToDenylist(bytes32)\":{\"params\":{\"_deniedUser\":\"accountId being banned\"}},\"addAccountsToAllowlist(bytes32[])\":{\"params\":{\"_allowedUsers\":\"List of accountIds allowed to signal intents on the user's deposit\"}},\"initialize(address,address)\":{\"params\":{\"_accountRegistrationProcessor\":\"Account Registration processor address\",\"_offRamperRegistrationProcessor\":\"Off-ramper Registration processor address\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"register(((string,string,string,string,address),bytes))\":{\"params\":{\"_proof\":\"Registration proof consisting of unredacted data being notarized and a signature\"}},\"registerAsOffRamper(((string,string,string,string),bytes))\":{\"params\":{\"_proof\":\"Registration proof consisting of unredacted data being notarized and a signature\"}},\"removeAccountFromDenylist(bytes32)\":{\"params\":{\"_approvedUser\":\"accountId being approved\"}},\"removeAccountsFromAllowlist(bytes32[])\":{\"params\":{\"_disallowedUsers\":\"List of accountIds being approved\"}},\"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.\"},\"setAccountRegistrationProcessor(address)\":{\"params\":{\"_registrationProcessor\":\"New registration proccesor address\"}},\"setOffRamperRegistrationProcessor(address)\":{\"params\":{\"_registrationProcessor\":\"New registration proccesor address\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addAccountToDenylist(bytes32)\":{\"notice\":\"Adds an accountId to a depositor's deny list. If an address associated with the banned accountId attempts to signal an intent on the user's deposit they will be denied.\"},\"addAccountsToAllowlist(bytes32[])\":{\"notice\":\"Adds passed accountIds to a depositor's allow list. All addresses associated with the allowed accountIds will be able to signal intents on the user's deposit.\"},\"enableAllowlist()\":{\"notice\":\"Enables allow list for user, only users on the allow list will be able to signal intents on the user's deposit.\"},\"initialize(address,address)\":{\"notice\":\"Initialize Ramp with the addresses of the Processors\"},\"register(((string,string,string,string,address),bytes))\":{\"notice\":\"Registers a new account by pulling the profileId from the proof and assigning the account owner to the sender of the transaction.\"},\"registerAsOffRamper(((string,string,string,string),bytes))\":{\"notice\":\"Registers an account for off-ramping by pulling the multi-currency account id from the proof and assigning the account owner to the sender of the transaction.\"},\"removeAccountFromDenylist(bytes32)\":{\"notice\":\"Removes an accountId from a depositor's deny list.\"},\"removeAccountsFromAllowlist(bytes32[])\":{\"notice\":\"Removes an passed accountId's from allow list. If allow list is enabled only users on the allow list will be able to signal intents on the user's deposit.\"},\"setAccountRegistrationProcessor(address)\":{\"notice\":\"GOVERNANCE ONLY: Updates the account registration processor address used for validating and interpreting tls proofs.\"},\"setOffRamperRegistrationProcessor(address)\":{\"notice\":\"GOVERNANCE ONLY: Updates the off ramper registration processor address used for validating and interpreting tls proofs.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ramps/wise/WiseAccountRegistry.sol\":\"WiseAccountRegistry\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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/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/external/Bytes32ArrayUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.17;\\n\\n/**\\n * @title Bytes32ArrayUtils\\n * @author ZKP2P\\n *\\n * Fork of Set Protocol's AddressArrayUtils library adapted for usage with bytes32 arrays.\\n */\\nlibrary Bytes32ArrayUtils {\\n\\n uint256 constant internal MAX_INT = 2**256 - 1;\\n\\n /**\\n * Finds the index of the first occurrence of the given element.\\n * @param A The input array to search\\n * @param a The value to find\\n * @return Returns (index and isIn) for the first occurrence starting from index 0\\n */\\n function indexOf(bytes32[] memory A, bytes32 a) internal pure returns (uint256, bool) {\\n uint256 length = A.length;\\n for (uint256 i = 0; i < length; i++) {\\n if (A[i] == a) {\\n return (i, true);\\n }\\n }\\n return (MAX_INT, false);\\n }\\n\\n /**\\n * Returns true if the value is present in the list. Uses indexOf internally.\\n * @param A The input array to search\\n * @param a The value to find\\n * @return Returns isIn for the first occurrence starting from index 0\\n */\\n function contains(bytes32[] memory A, bytes32 a) internal pure returns (bool) {\\n (, bool isIn) = indexOf(A, a);\\n return isIn;\\n }\\n\\n /**\\n * Returns true if there are 2 elements that are the same in an array\\n * @param A The input array to search\\n * @return Returns boolean for the first occurrence of a duplicate\\n */\\n function hasDuplicate(bytes32[] memory A) internal pure returns(bool) {\\n require(A.length > 0, \\\"A is empty\\\");\\n\\n for (uint256 i = 0; i < A.length - 1; i++) {\\n bytes32 current = A[i];\\n for (uint256 j = i + 1; j < A.length; j++) {\\n if (current == A[j]) {\\n return true;\\n }\\n }\\n }\\n return false;\\n }\\n\\n /**\\n * @param A The input array to search\\n * @param a The bytes32 to remove\\n * @return Returns the array with the object removed.\\n */\\n function remove(bytes32[] memory A, bytes32 a)\\n internal\\n pure\\n returns (bytes32[] memory)\\n {\\n (uint256 index, bool isIn) = indexOf(A, a);\\n if (!isIn) {\\n revert(\\\"bytes32 not in array.\\\");\\n } else {\\n (bytes32[] memory _A,) = pop(A, index);\\n return _A;\\n }\\n }\\n\\n /**\\n * @param A The input array to search\\n * @param a The bytes32 to remove\\n */\\n function removeStorage(bytes32[] storage A, bytes32 a)\\n internal\\n {\\n (uint256 index, bool isIn) = indexOf(A, a);\\n if (!isIn) {\\n revert(\\\"bytes32 not in array.\\\");\\n } else {\\n uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here\\n if (index != lastIndex) { A[index] = A[lastIndex]; }\\n A.pop();\\n }\\n }\\n\\n /**\\n * Removes specified index from array\\n * @param A The input array to search\\n * @param index The index to remove\\n * @return Returns the new array and the removed entry\\n */\\n function pop(bytes32[] memory A, uint256 index)\\n internal\\n pure\\n returns (bytes32[] memory, bytes32)\\n {\\n uint256 length = A.length;\\n require(index < A.length, \\\"Index must be < A length\\\");\\n bytes32[] memory newBytes = new bytes32[](length - 1);\\n for (uint256 i = 0; i < index; i++) {\\n newBytes[i] = A[i];\\n }\\n for (uint256 j = index + 1; j < length; j++) {\\n newBytes[j - 1] = A[j];\\n }\\n return (newBytes, A[index]);\\n }\\n}\\n\",\"keccak256\":\"0x14d572deda126ff812eb5ab0eed33120e13cc568fd611a4a6bff652f3e8440a8\",\"license\":\"MIT\"},\"contracts/external/Uint256ArrayUtils.sol\":{\"content\":\"/*\\n Copyright 2020 Set Labs Inc.\\n\\n Licensed under the Apache License, Version 2.0 (the \\\"License\\\");\\n you may not use this file except in compliance with the License.\\n You may obtain a copy of the License at\\n\\n http://www.apache.org/licenses/LICENSE-2.0\\n\\n Unless required by applicable law or agreed to in writing, software\\n distributed under the License is distributed on an \\\"AS IS\\\" BASIS,\\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\\n See the License for the specific language governing permissions and\\n limitations under the License.\\n\\n SPDX-License-Identifier: Apache-2.0\\n*/\\n\\npragma solidity ^0.8.18;\\n\\n/**\\n * @title Uint256ArrayUtils\\n * @author Set Protocol\\n *\\n * Utility functions to handle Uint256 Arrays\\n */\\nlibrary Uint256ArrayUtils {\\n\\n uint256 constant internal MAX_INT = 2**256 - 1;\\n\\n /**\\n * Finds the index of the first occurrence of the given element.\\n * @param A The input array to search\\n * @param a The value to find\\n * @return Returns (index and isIn) for the first occurrence starting from index 0\\n */\\n function indexOf(uint256[] memory A, uint256 a) internal pure returns (uint256, bool) {\\n uint256 length = A.length;\\n for (uint256 i = 0; i < length; i++) {\\n if (A[i] == a) {\\n return (i, true);\\n }\\n }\\n return (MAX_INT, false);\\n }\\n\\n /**\\n * Returns the combination of the two arrays\\n * @param A The first array\\n * @param B The second array\\n * @return Returns A extended by B\\n */\\n function extend(uint256[] memory A, uint256[] memory B) internal pure returns (uint256[] memory) {\\n uint256 aLength = A.length;\\n uint256 bLength = B.length;\\n uint256[] memory newUints = new uint256[](aLength + bLength);\\n for (uint256 i = 0; i < aLength; i++) {\\n newUints[i] = A[i];\\n }\\n for (uint256 j = 0; j < bLength; j++) {\\n newUints[aLength + j] = B[j];\\n }\\n return newUints;\\n }\\n\\n /**\\n * @param A The input array to search\\n * @param a The bytes32 to remove\\n */\\n function removeStorage(uint256[] storage A, uint256 a)\\n internal\\n {\\n (uint256 index, bool isIn) = indexOf(A, a);\\n if (!isIn) {\\n revert(\\\"uint256 not in array.\\\");\\n } else {\\n uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here\\n if (index != lastIndex) { A[index] = A[lastIndex]; }\\n A.pop();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x102021415f8444ff563fc6d0082f39296f47c09ce73fb4cd642e700ac489eefe\",\"license\":\"Apache-2.0\"},\"contracts/ramps/wise/WiseAccountRegistry.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport { Bytes32ArrayUtils } from \\\"../../external/Bytes32ArrayUtils.sol\\\";\\nimport { Uint256ArrayUtils } from \\\"../../external/Uint256ArrayUtils.sol\\\";\\n\\nimport { IWiseAccountRegistrationProcessor } from \\\"./interfaces/IWiseAccountRegistrationProcessor.sol\\\";\\nimport { IWiseAccountRegistry } from \\\"./interfaces/IWiseAccountRegistry.sol\\\";\\nimport { IWiseOffRamperRegistrationProcessor } from \\\"./interfaces/IWiseOffRamperRegistrationProcessor.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract WiseAccountRegistry is IWiseAccountRegistry, Ownable {\\n using Bytes32ArrayUtils for bytes32[];\\n using Uint256ArrayUtils for uint256[];\\n\\n /* ============ Events ============ */\\n event AccountRegistered(address indexed accountOwner, bytes32 indexed accountId, bytes32 indexed wiseTagHash);\\n event OffRamperRegistered(address indexed accountOwner, bytes32 indexed accountId, bytes32 indexed offRampId);\\n\\n event UserAddedToDenylist(bytes32 listOwner, bytes32 deniedUser);\\n event UserRemovedFromDenylist(bytes32 listOwner, bytes32 approvedUser);\\n\\n event AllowlistEnabled(bytes32 listOwner);\\n event UserAddedToAllowlist(bytes32 indexed listOwner, bytes32 allowedUser);\\n event UserRemovedFromAllowlist(bytes32 indexed listOwner, bytes32 allowedUser);\\n\\n event NewAccountRegistrationProcessorSet(address registrationProcessor);\\n event NewOffRamperRegistrationProcessorSet(address registrationProcessor);\\n\\n /* ============ Structs ============ */\\n\\n struct DenyList {\\n bytes32[] deniedUsers; // Array of accountIds that are denied from taking depositors liquidity\\n mapping(bytes32 => bool) isDenied; // Mapping of accountId to boolean indicating if the user is denied\\n }\\n\\n struct AllowList {\\n bool isEnabled; // Boolean indicating if the allowlist is enabled\\n bytes32[] allowedUsers; // Array of accountIds that are allowed from taking depositors liquidity\\n mapping(bytes32 => bool) isAllowed; // Mapping of accountId to boolean indicating if the user is allowed\\n }\\n\\n /* ============ Modifiers ============ */\\n modifier onlyRegisteredUser() {\\n require(isRegisteredUser(msg.sender), \\\"Caller must be registered user\\\");\\n _;\\n }\\n\\n /* ============ State Variables ============ */\\n IWiseAccountRegistrationProcessor public accountRegistrationProcessor; // Address of Account registration processor contract\\n IWiseOffRamperRegistrationProcessor public offRamperRegistrationProcessor; // Address of Off-ramper registration processor contract\\n\\n bool public isInitialized; // Indicates if contract has been initialized\\n\\n mapping(address => AccountInfo) internal accounts; // Mapping of Ethereum accounts to their account information (IDs and deposits)\\n mapping(bytes32 => DenyList) internal denyList; // Mapping of accountId to denylist\\n mapping(bytes32 => AllowList) internal allowList; // Mapping of accountId to allow list\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _owner\\n )\\n Ownable()\\n {\\n transferOwnership(_owner);\\n }\\n\\n /* ============ External Functions ============ */\\n\\n /**\\n * @notice Initialize Ramp with the addresses of the Processors\\n *\\n * @param _accountRegistrationProcessor Account Registration processor address\\n * @param _offRamperRegistrationProcessor Off-ramper Registration processor address\\n */\\n function initialize(\\n IWiseAccountRegistrationProcessor _accountRegistrationProcessor,\\n IWiseOffRamperRegistrationProcessor _offRamperRegistrationProcessor\\n )\\n external\\n onlyOwner\\n {\\n require(!isInitialized, \\\"Already initialized\\\");\\n\\n accountRegistrationProcessor = _accountRegistrationProcessor;\\n offRamperRegistrationProcessor = _offRamperRegistrationProcessor;\\n\\n isInitialized = true;\\n }\\n\\n /**\\n * @notice Registers a new account by pulling the profileId from the proof and assigning the account owner to the\\n * sender of the transaction.\\n *\\n * @param _proof Registration proof consisting of unredacted data being notarized and a signature\\n */\\n function register(\\n IWiseAccountRegistrationProcessor.RegistrationProof calldata _proof\\n )\\n external\\n {\\n require(msg.sender == _proof.public_values.userAddress, \\\"Caller must be address specified in proof\\\");\\n require(accounts[msg.sender].accountId == bytes32(0), \\\"Account already associated with accountId\\\");\\n (\\n bytes32 accountId,\\n bytes32 wiseTagHash\\n ) = _verifyRegistrationProof(_proof);\\n\\n accounts[msg.sender].accountId = accountId;\\n accounts[msg.sender].wiseTagHash = wiseTagHash;\\n\\n emit AccountRegistered(msg.sender, accountId, wiseTagHash);\\n }\\n\\n /**\\n * @notice Registers an account for off-ramping by pulling the multi-currency account id from the proof and assigning\\n * the account owner to the sender of the transaction.\\n *\\n * @param _proof Registration proof consisting of unredacted data being notarized and a signature\\n */\\n function registerAsOffRamper(\\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof calldata _proof\\n )\\n external\\n onlyRegisteredUser\\n {\\n require(accounts[msg.sender].offRampId == bytes32(0), \\\"Account already associated with offRampId\\\");\\n (\\n bytes32 accountId,\\n bytes32 offRampId\\n ) = _verifyOffRamperRegistrationProof(_proof);\\n\\n accounts[msg.sender].offRampId = offRampId;\\n\\n emit OffRamperRegistered(msg.sender, accountId, offRampId);\\n }\\n\\n /**\\n * @notice Adds an accountId to a depositor's deny list. If an address associated with the banned accountId attempts to\\n * signal an intent on the user's deposit they will be denied.\\n *\\n * @param _deniedUser accountId being banned\\n */\\n function addAccountToDenylist(bytes32 _deniedUser) external onlyRegisteredUser {\\n bytes32 denyingUser = accounts[msg.sender].accountId;\\n\\n require(!denyList[denyingUser].isDenied[_deniedUser], \\\"User already on denylist\\\");\\n\\n denyList[denyingUser].isDenied[_deniedUser] = true;\\n denyList[denyingUser].deniedUsers.push(_deniedUser);\\n\\n emit UserAddedToDenylist(denyingUser, _deniedUser);\\n }\\n\\n /**\\n * @notice Removes an accountId from a depositor's deny list.\\n *\\n * @param _approvedUser accountId being approved\\n */\\n function removeAccountFromDenylist(bytes32 _approvedUser) external onlyRegisteredUser {\\n bytes32 approvingUser = accounts[msg.sender].accountId;\\n\\n require(denyList[approvingUser].isDenied[_approvedUser], \\\"User not on denylist\\\");\\n\\n denyList[approvingUser].isDenied[_approvedUser] = false;\\n denyList[approvingUser].deniedUsers.removeStorage(_approvedUser);\\n\\n emit UserRemovedFromDenylist(approvingUser, _approvedUser);\\n }\\n\\n /**\\n * @notice Enables allow list for user, only users on the allow list will be able to signal intents on the user's deposit.\\n */\\n function enableAllowlist() external onlyRegisteredUser {\\n bytes32 allowingUser = accounts[msg.sender].accountId;\\n\\n require(!allowList[allowingUser].isEnabled, \\\"Allow list already enabled\\\");\\n\\n allowList[allowingUser].isEnabled = true;\\n\\n emit AllowlistEnabled(allowingUser);\\n }\\n\\n /**\\n * @notice Adds passed accountIds to a depositor's allow list. All addresses associated with the allowed accountIds will\\n * be able to signal intents on the user's deposit.\\n *\\n * @param _allowedUsers List of accountIds allowed to signal intents on the user's deposit\\n */\\n function addAccountsToAllowlist(bytes32[] memory _allowedUsers) external onlyRegisteredUser {\\n bytes32 allowingUser = accounts[msg.sender].accountId;\\n\\n for(uint256 i = 0; i < _allowedUsers.length; i++) {\\n bytes32 allowedUser = _allowedUsers[i];\\n\\n require(!allowList[allowingUser].isAllowed[allowedUser], \\\"User already on allowlist\\\");\\n\\n allowList[allowingUser].isAllowed[allowedUser] = true;\\n allowList[allowingUser].allowedUsers.push(allowedUser);\\n\\n emit UserAddedToAllowlist(allowingUser, allowedUser);\\n }\\n }\\n\\n /**\\n * @notice Removes an passed accountId's from allow list. If allow list is enabled only users on the allow list will be\\n * able to signal intents on the user's deposit.\\n *\\n * @param _disallowedUsers List of accountIds being approved\\n */\\n function removeAccountsFromAllowlist(bytes32[] memory _disallowedUsers) external onlyRegisteredUser {\\n bytes32 disallowingUser = accounts[msg.sender].accountId;\\n\\n for(uint256 i = 0; i < _disallowedUsers.length; i++) {\\n bytes32 disallowedUser = _disallowedUsers[i];\\n\\n require(allowList[disallowingUser].isAllowed[disallowedUser], \\\"User not on allowlist\\\");\\n\\n allowList[disallowingUser].isAllowed[disallowedUser] = false;\\n allowList[disallowingUser].allowedUsers.removeStorage(disallowedUser);\\n\\n emit UserRemovedFromAllowlist(disallowingUser, disallowedUser);\\n }\\n }\\n\\n /* ============ Governance Functions ============ */\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the account registration processor address used for validating and interpreting tls proofs.\\n *\\n * @param _registrationProcessor New registration proccesor address\\n */\\n function setAccountRegistrationProcessor(IWiseAccountRegistrationProcessor _registrationProcessor) external onlyOwner {\\n accountRegistrationProcessor = _registrationProcessor;\\n emit NewAccountRegistrationProcessorSet(address(_registrationProcessor));\\n }\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the off ramper registration processor address used for validating and interpreting tls proofs.\\n *\\n * @param _registrationProcessor New registration proccesor address\\n */\\n function setOffRamperRegistrationProcessor(IWiseOffRamperRegistrationProcessor _registrationProcessor) external onlyOwner {\\n offRamperRegistrationProcessor = _registrationProcessor;\\n emit NewOffRamperRegistrationProcessorSet(address(_registrationProcessor));\\n }\\n\\n /* ============ External View Functions ============ */\\n\\n function getAccountInfo(address _account) external view returns (AccountInfo memory) {\\n return accounts[_account];\\n }\\n\\n function getAccountId(address _account) public view returns (bytes32) {\\n return accounts[_account].accountId;\\n }\\n\\n function isRegisteredUser(address _account) public view returns (bool) {\\n return getAccountId(_account) != bytes32(0);\\n }\\n\\n function getDeniedUsers(address _account) external view returns (bytes32[] memory) {\\n return denyList[getAccountId(_account)].deniedUsers;\\n }\\n\\n function isDeniedUser(address _account, bytes32 _deniedUser) external view returns (bool) {\\n return denyList[getAccountId(_account)].isDenied[_deniedUser];\\n }\\n\\n function isAllowlistEnabled(address _account) external view returns (bool) {\\n return allowList[getAccountId(_account)].isEnabled;\\n }\\n\\n function getAllowedUsers(address _account) external view returns (bytes32[] memory) {\\n return allowList[getAccountId(_account)].allowedUsers;\\n }\\n\\n function isAllowedUser(address _account, bytes32 _allowedUser) external view returns (bool) {\\n bytes32 allowingUser = getAccountId(_account);\\n\\n // Deny list overrides, if user on deny list then they are not allowed\\n if(denyList[allowingUser].isDenied[_allowedUser]) { return false; }\\n\\n // Check if allow list is enabled, if so return status of user, else return true\\n return allowList[allowingUser].isEnabled ? allowList[allowingUser].isAllowed[_allowedUser] : true;\\n }\\n \\n /* ============ Internal Functions ============ */\\n\\n /**\\n * @notice Validate the user has an Wise account, we do not nullify this email since it can be reused to register under\\n * different addresses.\\n */\\n function _verifyRegistrationProof(\\n IWiseAccountRegistrationProcessor.RegistrationProof calldata _proof\\n )\\n internal\\n returns(bytes32 accountId, bytes32 wiseTagHash)\\n {\\n (\\n accountId,\\n wiseTagHash\\n ) = accountRegistrationProcessor.processProof(_proof);\\n }\\n\\n /**\\n * @notice Validate the user has an Wise account, we do not nullify this email since it can be reused to register under\\n * different addresses.\\n */\\n function _verifyOffRamperRegistrationProof(\\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof calldata _proof\\n )\\n internal\\n returns(bytes32 accountId, bytes32 offRampId)\\n {\\n (\\n accountId,\\n offRampId\\n ) = offRamperRegistrationProcessor.processProof(_proof);\\n\\n require(accountId == accounts[msg.sender].accountId, \\\"AccountId does not match\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc7af7d788641fbd85afc9435ac1cb993a5011f88b14b1af87c6748bd65bdc326\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseAccountRegistrationProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseAccountRegistrationProcessor {\\n\\n struct RegistrationData {\\n string endpoint;\\n string host;\\n string profileId;\\n string wiseTagHash;\\n address userAddress;\\n }\\n\\n struct RegistrationProof {\\n RegistrationData public_values;\\n bytes proof;\\n }\\n\\n function processProof(\\n RegistrationProof calldata _proof\\n )\\n external\\n returns (bytes32, bytes32);\\n}\\n\",\"keccak256\":\"0x2a8373601ac246f684f1a92b111a245fe3c6d3d57d6abcb4e00bd8eeae734631\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseAccountRegistry.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseAccountRegistry {\\n\\n // Each Account is tied to a Wise ID and is represented by an Ethereum address.\\n struct AccountInfo {\\n bytes32 accountId; // User's Wise account ID\\n bytes32 offRampId; // Multi-currency account ID to receive funds\\n bytes32 wiseTagHash; // Hash of user's wise tag account stored on register. Used to verify offramper's wise tag\\n }\\n\\n function getAccountInfo(address _account) external view returns (AccountInfo memory);\\n function getAccountId(address _account) external view returns (bytes32);\\n\\n function isRegisteredUser(address _account) external view returns (bool);\\n \\n function isAllowedUser(address _account, bytes32 _deniedUser) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xfaf30dc7e7dd1a0bce25c0188059b17bde3929fb473570bc8860a82ae97c5b35\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseOffRamperRegistrationProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseOffRamperRegistrationProcessor {\\n\\n struct OffRamperRegistrationData {\\n string endpoint;\\n string host;\\n string profileId;\\n string mcAccountId;\\n }\\n\\n struct OffRamperRegistrationProof {\\n OffRamperRegistrationData public_values;\\n bytes proof;\\n }\\n\\n function processProof(\\n OffRamperRegistrationProof calldata _proof\\n )\\n external\\n returns (bytes32, bytes32);\\n}\\n\",\"keccak256\":\"0x1ca016325effca3a3d66ffa59d5a6bb694f4daca8ba9d57542f1beea73f2ceec\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b5060405162001a8238038062001a82833981016040819052620000349162000182565b6200003f3362000051565b6200004a81620000a1565b50620001b4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620000ab62000124565b6001600160a01b038116620001165760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001218162000051565b50565b6000546001600160a01b03163314620001805760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200010d565b565b6000602082840312156200019557600080fd5b81516001600160a01b0381168114620001ad57600080fd5b9392505050565b6118be80620001c46000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c8063715018a6116100c3578063c6a2aac81161007c578063c6a2aac814610356578063d88452451461035e578063e0b490f714610371578063e39ca3b414610392578063f2fde38b146103a5578063fbf15b1f146103b857600080fd5b8063715018a61461027e5780637b510fe8146102865780638da5cb5b1461030c5780639b357b5a1461031d578063b14fac2e14610330578063c3eb86811461034357600080fd5b80633056eb28116101155780633056eb28146101fe57806338e4bef614610211578063392e53cd146102245780634595bba014610238578063485cc95514610258578063605958f41461026b57600080fd5b80630876dda31461015d5780630f29d4c51461018d578063148172da146101a25780631acd84d8146101b55780631e48fe6b146101d85780631f5bdf5d146101eb575b600080fd5b600154610170906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101a061019b366004611339565b6103cb565b005b6101a06101b036600461136e565b610524565b6101c86101c336600461139c565b610642565b6040519015158152602001610184565b6101a06101e63660046113de565b6106c8565b6101c86101f936600461149c565b610817565b6101a061020c36600461149c565b61082b565b6101c861021f36600461149c565b610888565b6002546101c890600160a01b900460ff1681565b61024b61024636600461149c565b6108b1565b60405161018491906114c0565b6101a0610266366004611504565b610927565b600254610170906001600160a01b031681565b6101a06109ba565b6102ea61029436600461149c565b6040805160608082018352600080835260208084018290529284018190526001600160a01b0394909416845260038252928290208251938401835280548452600181015491840191909152600201549082015290565b6040805182518152602080840151908201529181015190820152606001610184565b6000546001600160a01b0316610170565b6101a061032b36600461136e565b6109ce565b6101a061033e366004611339565b610acd565b6101a061035136600461149c565b610bb9565b6101a0610c0f565b6101a061036c3660046113de565b610cee565b61038461037f36600461149c565b610e49565b604051908152602001610184565b61024b6103a036600461149c565b610e64565b6101a06103b336600461149c565b610ed8565b6101c86103c636600461139c565b610f51565b6103d5818061153d565b6103e69060a081019060800161149c565b6001600160a01b0316336001600160a01b03161461045d5760405162461bcd60e51b815260206004820152602960248201527f43616c6c6572206d7573742062652061646472657373207370656369666965646044820152681034b710383937b7b360b91b60648201526084015b60405180910390fd5b33600090815260036020526040902054156104cc5760405162461bcd60e51b815260206004820152602960248201527f4163636f756e7420616c7265616479206173736f6369617465642077697468206044820152681858d8dbdd5b9d125960ba1b6064820152608401610454565b6000806104d883610f8c565b3360008181526003602052604080822085815560020184905551939550919350839285927fcc65223c6e9df339af3ea6f6f0bf09fa478060d7c745142bdccb626ef62c79e291a4505050565b61052d33610817565b6105495760405162461bcd60e51b81526004016104549061155d565b33600090815260036020908152604080832054808452600483528184208585526001019092529091205460ff16156105c35760405162461bcd60e51b815260206004820152601860248201527f5573657220616c7265616479206f6e2064656e796c69737400000000000000006044820152606401610454565b600081815260046020818152604080842086855260018181018452828620805460ff191682179055938352805493840181558452922001839055517f976c693d56f27ba17d902bda80c4fa0416b773fbf268bcb0ee71689234d769ee906106369083908590918252602082015260400190565b60405180910390a15050565b60008061064e84610e49565b600081815260046020908152604080832087845260010190915290205490915060ff16156106805760009150506106c2565b60008181526005602052604090205460ff1661069d5760016106be565b600081815260056020908152604080832086845260020190915290205460ff165b9150505b92915050565b6106d133610817565b6106ed5760405162461bcd60e51b81526004016104549061155d565b33600090815260036020526040812054905b825181101561081257600083828151811061071c5761071c611594565b6020908102919091018101516000858152600583526040808220838352600201909352919091205490915060ff1661078e5760405162461bcd60e51b8152602060048201526015602482015274155cd95c881b9bdd081bdb88185b1b1bdddb1a5cdd605a1b6044820152606401610454565b6000838152600560208181526040808420858552600281018352908420805460ff1916905592869052526107c5906001018261100d565b827fe87ba7050133e8b4c8b879f99b3276368eaca3b81f4ea415d9528843a15d8c63826040516107f791815260200190565b60405180910390a2508061080a816115c0565b9150506106ff565b505050565b60008061082383610e49565b141592915050565b610833611135565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527ffd4e734c9a89ace3649766f5233487313285fe97ca577c2602beda889ef46dd3906020015b60405180910390a150565b60006005600061089784610e49565b815260208101919091526040016000205460ff1692915050565b6060600460006108c084610e49565b815260200190815260200160002060000180548060200260200160405190810160405280929190818152602001828054801561091b57602002820191906000526020600020905b815481526020019060010190808311610907575b50505050509050919050565b61092f611135565b600254600160a01b900460ff161561097f5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610454565b600180546001600160a01b039384166001600160a01b0319909116179055600280546001600160a81b0319169190921617600160a01b179055565b6109c2611135565b6109cc600061118f565b565b6109d733610817565b6109f35760405162461bcd60e51b81526004016104549061155d565b33600090815260036020908152604080832054808452600483528184208585526001019092529091205460ff16610a635760405162461bcd60e51b8152602060048201526014602482015273155cd95c881b9bdd081bdb8819195b9e5b1a5cdd60621b6044820152606401610454565b6000818152600460208181526040808420868552600181018352908420805460ff191690559284905252610a97908361100d565b60408051828152602081018490527f8935205b1b382095d2d95efbb36f81a11a34c548d45af26adc1a02d2f2bb546f9101610636565b610ad633610817565b610af25760405162461bcd60e51b81526004016104549061155d565b3360009081526003602052604090206001015415610b645760405162461bcd60e51b815260206004820152602960248201527f4163636f756e7420616c7265616479206173736f6369617465642077697468206044820152681bd99994985b5c125960ba1b6064820152608401610454565b600080610b70836111df565b3360008181526003602052604080822060010184905551939550919350839285927f1145ead7f8f95549bd8948731c7e50cda0ef6a0bba6867ee9e383633c2de4c2091a4505050565b610bc1611135565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f32bce9e8b6bd060cc566144f14693fad172bd139e984b38c7c83c6d29ef1ad489060200161087d565b610c1833610817565b610c345760405162461bcd60e51b81526004016104549061155d565b3360009081526003602090815260408083205480845260059092529091205460ff1615610ca35760405162461bcd60e51b815260206004820152601a60248201527f416c6c6f77206c69737420616c726561647920656e61626c65640000000000006044820152606401610454565b60008181526005602052604090819020805460ff19166001179055517f08df0a71ea3e5565a2138936ed06eaba47996a3ccfde2dae1f3edd1164e299d79061087d9083815260200190565b610cf733610817565b610d135760405162461bcd60e51b81526004016104549061155d565b33600090815260036020526040812054905b8251811015610812576000838281518110610d4257610d42611594565b6020908102919091018101516000858152600583526040808220838352600201909352919091205490915060ff1615610dbd5760405162461bcd60e51b815260206004820152601960248201527f5573657220616c7265616479206f6e20616c6c6f776c697374000000000000006044820152606401610454565b6000838152600560208181526040808420858552600281018352818520805460ff1916600190811790915593835283018054938401815584529220018290555183907f857ce673abc5a303fa8303102f12b42079aa85b97bca15b56428764dd1dec4d290610e2e9084815260200190565b60405180910390a25080610e41816115c0565b915050610d25565b6001600160a01b031660009081526003602052604090205490565b606060056000610e7384610e49565b815260200190815260200160002060010180548060200260200160405190810160405280929190818152602001828054801561091b57602002820191906000526020600020908154815260200190600101908083116109075750505050509050919050565b610ee0611135565b6001600160a01b038116610f455760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610454565b610f4e8161118f565b50565b600060046000610f6085610e49565b81526020808201929092526040908101600090812085825260010190925290205460ff16905092915050565b600154604051635e0b6e9b60e01b815260009182916001600160a01b0390911690635e0b6e9b90610fc1908690600401611648565b60408051808303816000875af1158015610fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110039190611757565b9094909350915050565b6000806110698480548060200260200160405190810160405280929190818152602001828054801561105e57602002820191906000526020600020905b81548152602001906001019080831161104a575b5050505050846112be565b91509150806110b25760405162461bcd60e51b8152602060048201526015602482015274313cba32b99999103737ba1034b71030b93930bc9760591b6044820152606401610454565b83546000906110c39060019061177b565b9050808314611108578481815481106110de576110de611594565b90600052602060002001548584815481106110fb576110fb611594565b6000918252602090912001555b848054806111185761111861178e565b600190038181906000526020600020016000905590555050505050565b6000546001600160a01b031633146109cc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60025460405163027c064960e51b815260009182916001600160a01b0390911690634f80c920906112149086906004016117a4565b60408051808303816000875af1158015611232573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112569190611757565b33600090815260036020526040902054919350915082146112b95760405162461bcd60e51b815260206004820152601860248201527f4163636f756e74496420646f6573206e6f74206d6174636800000000000000006044820152606401610454565b915091565b81516000908190815b8181101561130e57848682815181106112e2576112e2611594565b6020026020010151036112fc5792506001915061131a9050565b80611306816115c0565b9150506112c7565b50600019600092509250505b9250929050565b60006040828403121561133357600080fd5b50919050565b60006020828403121561134b57600080fd5b813567ffffffffffffffff81111561136257600080fd5b6106be84828501611321565b60006020828403121561138057600080fd5b5035919050565b6001600160a01b0381168114610f4e57600080fd5b600080604083850312156113af57600080fd5b82356113ba81611387565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600060208083850312156113f157600080fd5b823567ffffffffffffffff8082111561140957600080fd5b818501915085601f83011261141d57600080fd5b81358181111561142f5761142f6113c8565b8060051b604051601f19603f83011681018181108582111715611454576114546113c8565b60405291825284820192508381018501918883111561147257600080fd5b938501935b8285101561149057843584529385019392850192611477565b98975050505050505050565b6000602082840312156114ae57600080fd5b81356114b981611387565b9392505050565b6020808252825182820181905260009190848201906040850190845b818110156114f8578351835292840192918401916001016114dc565b50909695505050505050565b6000806040838503121561151757600080fd5b823561152281611387565b9150602083013561153281611387565b809150509250929050565b60008235609e1983360301811261155357600080fd5b9190910192915050565b6020808252601e908201527f43616c6c6572206d757374206265207265676973746572656420757365720000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016115d2576115d26115aa565b5060010190565b6000808335601e198436030181126115f057600080fd5b830160208101925035905067ffffffffffffffff81111561161057600080fd5b80360382131561131a57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260008235609e1984360301811261166257600080fd5b60406020840152830161167581806115d9565b60a0606086015261168b6101008601828461161f565b91505061169b60208301836115d9565b605f19808785030160808801526116b384838561161f565b93506116c260408601866115d9565b93509150808785030160a08801526116db84848461161f565b93506116ea60608601866115d9565b93509150808785030160c08801525061170483838361161f565b925050506080820135915061171882611387565b6001600160a01b03821660e085015261173460208601866115d9565b858303601f19016040870152925061174d82848361161f565b9695505050505050565b6000806040838503121561176a57600080fd5b505080516020909101519092909150565b818103818111156106c2576106c26115aa565b634e487b7160e01b600052603160045260246000fd5b6020815260008235607e198436030181126117be57600080fd5b6040602084015283016117d181806115d9565b608060608601526117e660e08601828461161f565b9150506117f660208301836115d9565b605f198087850301608088015261180e84838561161f565b935061181d60408601866115d9565b93509150808785030160a088015261183684848461161f565b935061184560608601866115d9565b95509250808785030160c0880152505061186082848361161f565b9250505061187160208501856115d9565b848303601f1901604086015261174d83828461161f56fea2646970667358221220f6834241fd8d555457b9123cd68085dfe9a82133219e6a045dd2e18fd5174ee464736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101585760003560e01c8063715018a6116100c3578063c6a2aac81161007c578063c6a2aac814610356578063d88452451461035e578063e0b490f714610371578063e39ca3b414610392578063f2fde38b146103a5578063fbf15b1f146103b857600080fd5b8063715018a61461027e5780637b510fe8146102865780638da5cb5b1461030c5780639b357b5a1461031d578063b14fac2e14610330578063c3eb86811461034357600080fd5b80633056eb28116101155780633056eb28146101fe57806338e4bef614610211578063392e53cd146102245780634595bba014610238578063485cc95514610258578063605958f41461026b57600080fd5b80630876dda31461015d5780630f29d4c51461018d578063148172da146101a25780631acd84d8146101b55780631e48fe6b146101d85780631f5bdf5d146101eb575b600080fd5b600154610170906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101a061019b366004611339565b6103cb565b005b6101a06101b036600461136e565b610524565b6101c86101c336600461139c565b610642565b6040519015158152602001610184565b6101a06101e63660046113de565b6106c8565b6101c86101f936600461149c565b610817565b6101a061020c36600461149c565b61082b565b6101c861021f36600461149c565b610888565b6002546101c890600160a01b900460ff1681565b61024b61024636600461149c565b6108b1565b60405161018491906114c0565b6101a0610266366004611504565b610927565b600254610170906001600160a01b031681565b6101a06109ba565b6102ea61029436600461149c565b6040805160608082018352600080835260208084018290529284018190526001600160a01b0394909416845260038252928290208251938401835280548452600181015491840191909152600201549082015290565b6040805182518152602080840151908201529181015190820152606001610184565b6000546001600160a01b0316610170565b6101a061032b36600461136e565b6109ce565b6101a061033e366004611339565b610acd565b6101a061035136600461149c565b610bb9565b6101a0610c0f565b6101a061036c3660046113de565b610cee565b61038461037f36600461149c565b610e49565b604051908152602001610184565b61024b6103a036600461149c565b610e64565b6101a06103b336600461149c565b610ed8565b6101c86103c636600461139c565b610f51565b6103d5818061153d565b6103e69060a081019060800161149c565b6001600160a01b0316336001600160a01b03161461045d5760405162461bcd60e51b815260206004820152602960248201527f43616c6c6572206d7573742062652061646472657373207370656369666965646044820152681034b710383937b7b360b91b60648201526084015b60405180910390fd5b33600090815260036020526040902054156104cc5760405162461bcd60e51b815260206004820152602960248201527f4163636f756e7420616c7265616479206173736f6369617465642077697468206044820152681858d8dbdd5b9d125960ba1b6064820152608401610454565b6000806104d883610f8c565b3360008181526003602052604080822085815560020184905551939550919350839285927fcc65223c6e9df339af3ea6f6f0bf09fa478060d7c745142bdccb626ef62c79e291a4505050565b61052d33610817565b6105495760405162461bcd60e51b81526004016104549061155d565b33600090815260036020908152604080832054808452600483528184208585526001019092529091205460ff16156105c35760405162461bcd60e51b815260206004820152601860248201527f5573657220616c7265616479206f6e2064656e796c69737400000000000000006044820152606401610454565b600081815260046020818152604080842086855260018181018452828620805460ff191682179055938352805493840181558452922001839055517f976c693d56f27ba17d902bda80c4fa0416b773fbf268bcb0ee71689234d769ee906106369083908590918252602082015260400190565b60405180910390a15050565b60008061064e84610e49565b600081815260046020908152604080832087845260010190915290205490915060ff16156106805760009150506106c2565b60008181526005602052604090205460ff1661069d5760016106be565b600081815260056020908152604080832086845260020190915290205460ff165b9150505b92915050565b6106d133610817565b6106ed5760405162461bcd60e51b81526004016104549061155d565b33600090815260036020526040812054905b825181101561081257600083828151811061071c5761071c611594565b6020908102919091018101516000858152600583526040808220838352600201909352919091205490915060ff1661078e5760405162461bcd60e51b8152602060048201526015602482015274155cd95c881b9bdd081bdb88185b1b1bdddb1a5cdd605a1b6044820152606401610454565b6000838152600560208181526040808420858552600281018352908420805460ff1916905592869052526107c5906001018261100d565b827fe87ba7050133e8b4c8b879f99b3276368eaca3b81f4ea415d9528843a15d8c63826040516107f791815260200190565b60405180910390a2508061080a816115c0565b9150506106ff565b505050565b60008061082383610e49565b141592915050565b610833611135565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527ffd4e734c9a89ace3649766f5233487313285fe97ca577c2602beda889ef46dd3906020015b60405180910390a150565b60006005600061089784610e49565b815260208101919091526040016000205460ff1692915050565b6060600460006108c084610e49565b815260200190815260200160002060000180548060200260200160405190810160405280929190818152602001828054801561091b57602002820191906000526020600020905b815481526020019060010190808311610907575b50505050509050919050565b61092f611135565b600254600160a01b900460ff161561097f5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610454565b600180546001600160a01b039384166001600160a01b0319909116179055600280546001600160a81b0319169190921617600160a01b179055565b6109c2611135565b6109cc600061118f565b565b6109d733610817565b6109f35760405162461bcd60e51b81526004016104549061155d565b33600090815260036020908152604080832054808452600483528184208585526001019092529091205460ff16610a635760405162461bcd60e51b8152602060048201526014602482015273155cd95c881b9bdd081bdb8819195b9e5b1a5cdd60621b6044820152606401610454565b6000818152600460208181526040808420868552600181018352908420805460ff191690559284905252610a97908361100d565b60408051828152602081018490527f8935205b1b382095d2d95efbb36f81a11a34c548d45af26adc1a02d2f2bb546f9101610636565b610ad633610817565b610af25760405162461bcd60e51b81526004016104549061155d565b3360009081526003602052604090206001015415610b645760405162461bcd60e51b815260206004820152602960248201527f4163636f756e7420616c7265616479206173736f6369617465642077697468206044820152681bd99994985b5c125960ba1b6064820152608401610454565b600080610b70836111df565b3360008181526003602052604080822060010184905551939550919350839285927f1145ead7f8f95549bd8948731c7e50cda0ef6a0bba6867ee9e383633c2de4c2091a4505050565b610bc1611135565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f32bce9e8b6bd060cc566144f14693fad172bd139e984b38c7c83c6d29ef1ad489060200161087d565b610c1833610817565b610c345760405162461bcd60e51b81526004016104549061155d565b3360009081526003602090815260408083205480845260059092529091205460ff1615610ca35760405162461bcd60e51b815260206004820152601a60248201527f416c6c6f77206c69737420616c726561647920656e61626c65640000000000006044820152606401610454565b60008181526005602052604090819020805460ff19166001179055517f08df0a71ea3e5565a2138936ed06eaba47996a3ccfde2dae1f3edd1164e299d79061087d9083815260200190565b610cf733610817565b610d135760405162461bcd60e51b81526004016104549061155d565b33600090815260036020526040812054905b8251811015610812576000838281518110610d4257610d42611594565b6020908102919091018101516000858152600583526040808220838352600201909352919091205490915060ff1615610dbd5760405162461bcd60e51b815260206004820152601960248201527f5573657220616c7265616479206f6e20616c6c6f776c697374000000000000006044820152606401610454565b6000838152600560208181526040808420858552600281018352818520805460ff1916600190811790915593835283018054938401815584529220018290555183907f857ce673abc5a303fa8303102f12b42079aa85b97bca15b56428764dd1dec4d290610e2e9084815260200190565b60405180910390a25080610e41816115c0565b915050610d25565b6001600160a01b031660009081526003602052604090205490565b606060056000610e7384610e49565b815260200190815260200160002060010180548060200260200160405190810160405280929190818152602001828054801561091b57602002820191906000526020600020908154815260200190600101908083116109075750505050509050919050565b610ee0611135565b6001600160a01b038116610f455760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610454565b610f4e8161118f565b50565b600060046000610f6085610e49565b81526020808201929092526040908101600090812085825260010190925290205460ff16905092915050565b600154604051635e0b6e9b60e01b815260009182916001600160a01b0390911690635e0b6e9b90610fc1908690600401611648565b60408051808303816000875af1158015610fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110039190611757565b9094909350915050565b6000806110698480548060200260200160405190810160405280929190818152602001828054801561105e57602002820191906000526020600020905b81548152602001906001019080831161104a575b5050505050846112be565b91509150806110b25760405162461bcd60e51b8152602060048201526015602482015274313cba32b99999103737ba1034b71030b93930bc9760591b6044820152606401610454565b83546000906110c39060019061177b565b9050808314611108578481815481106110de576110de611594565b90600052602060002001548584815481106110fb576110fb611594565b6000918252602090912001555b848054806111185761111861178e565b600190038181906000526020600020016000905590555050505050565b6000546001600160a01b031633146109cc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60025460405163027c064960e51b815260009182916001600160a01b0390911690634f80c920906112149086906004016117a4565b60408051808303816000875af1158015611232573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112569190611757565b33600090815260036020526040902054919350915082146112b95760405162461bcd60e51b815260206004820152601860248201527f4163636f756e74496420646f6573206e6f74206d6174636800000000000000006044820152606401610454565b915091565b81516000908190815b8181101561130e57848682815181106112e2576112e2611594565b6020026020010151036112fc5792506001915061131a9050565b80611306816115c0565b9150506112c7565b50600019600092509250505b9250929050565b60006040828403121561133357600080fd5b50919050565b60006020828403121561134b57600080fd5b813567ffffffffffffffff81111561136257600080fd5b6106be84828501611321565b60006020828403121561138057600080fd5b5035919050565b6001600160a01b0381168114610f4e57600080fd5b600080604083850312156113af57600080fd5b82356113ba81611387565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600060208083850312156113f157600080fd5b823567ffffffffffffffff8082111561140957600080fd5b818501915085601f83011261141d57600080fd5b81358181111561142f5761142f6113c8565b8060051b604051601f19603f83011681018181108582111715611454576114546113c8565b60405291825284820192508381018501918883111561147257600080fd5b938501935b8285101561149057843584529385019392850192611477565b98975050505050505050565b6000602082840312156114ae57600080fd5b81356114b981611387565b9392505050565b6020808252825182820181905260009190848201906040850190845b818110156114f8578351835292840192918401916001016114dc565b50909695505050505050565b6000806040838503121561151757600080fd5b823561152281611387565b9150602083013561153281611387565b809150509250929050565b60008235609e1983360301811261155357600080fd5b9190910192915050565b6020808252601e908201527f43616c6c6572206d757374206265207265676973746572656420757365720000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016115d2576115d26115aa565b5060010190565b6000808335601e198436030181126115f057600080fd5b830160208101925035905067ffffffffffffffff81111561161057600080fd5b80360382131561131a57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260008235609e1984360301811261166257600080fd5b60406020840152830161167581806115d9565b60a0606086015261168b6101008601828461161f565b91505061169b60208301836115d9565b605f19808785030160808801526116b384838561161f565b93506116c260408601866115d9565b93509150808785030160a08801526116db84848461161f565b93506116ea60608601866115d9565b93509150808785030160c08801525061170483838361161f565b925050506080820135915061171882611387565b6001600160a01b03821660e085015261173460208601866115d9565b858303601f19016040870152925061174d82848361161f565b9695505050505050565b6000806040838503121561176a57600080fd5b505080516020909101519092909150565b818103818111156106c2576106c26115aa565b634e487b7160e01b600052603160045260246000fd5b6020815260008235607e198436030181126117be57600080fd5b6040602084015283016117d181806115d9565b608060608601526117e660e08601828461161f565b9150506117f660208301836115d9565b605f198087850301608088015261180e84838561161f565b935061181d60408601866115d9565b93509150808785030160a088015261183684848461161f565b935061184560608601866115d9565b95509250808785030160c0880152505061186082848361161f565b9250505061187160208501856115d9565b848303601f1901604086015261174d83828461161f56fea2646970667358221220f6834241fd8d555457b9123cd68085dfe9a82133219e6a045dd2e18fd5174ee464736f6c63430008120033", "devdoc": { "kind": "dev", "methods": { @@ -720,7 +725,7 @@ "owner()": { "details": "Returns the address of the current owner." }, - "register(((string,string,string,string),bytes))": { + "register(((string,string,string,string,address),bytes))": { "params": { "_proof": "Registration proof consisting of unredacted data being notarized and a signature" } @@ -774,7 +779,7 @@ "initialize(address,address)": { "notice": "Initialize Ramp with the addresses of the Processors" }, - "register(((string,string,string,string),bytes))": { + "register(((string,string,string,string,address),bytes))": { "notice": "Registers a new account by pulling the profileId from the proof and assigning the account owner to the sender of the transaction." }, "registerAsOffRamper(((string,string,string,string),bytes))": { @@ -806,23 +811,23 @@ "type": "t_address" }, { - "astId": 18056, + "astId": 3339, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "accountRegistrationProcessor", "offset": 0, "slot": "1", - "type": "t_contract(IWiseAccountRegistrationProcessor)21075" + "type": "t_contract(IWiseAccountRegistrationProcessor)6323" }, { - "astId": 18059, + "astId": 3342, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "offRamperRegistrationProcessor", "offset": 0, "slot": "2", - "type": "t_contract(IWiseOffRamperRegistrationProcessor)21144" + "type": "t_contract(IWiseOffRamperRegistrationProcessor)6392" }, { - "astId": 18061, + "astId": 3344, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "isInitialized", "offset": 20, @@ -830,28 +835,28 @@ "type": "t_bool" }, { - "astId": 18066, + "astId": 3349, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "accounts", "offset": 0, "slot": "3", - "type": "t_mapping(t_address,t_struct(AccountInfo)21084_storage)" + "type": "t_mapping(t_address,t_struct(AccountInfo)6332_storage)" }, { - "astId": 18071, + "astId": 3354, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "denyList", "offset": 0, "slot": "4", - "type": "t_mapping(t_bytes32,t_struct(DenyList)18031_storage)" + "type": "t_mapping(t_bytes32,t_struct(DenyList)3314_storage)" }, { - "astId": 18076, + "astId": 3359, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "allowList", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(AllowList)18041_storage)" + "type": "t_mapping(t_bytes32,t_struct(AllowList)3324_storage)" } ], "types": { @@ -876,22 +881,22 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_contract(IWiseAccountRegistrationProcessor)21075": { + "t_contract(IWiseAccountRegistrationProcessor)6323": { "encoding": "inplace", "label": "contract IWiseAccountRegistrationProcessor", "numberOfBytes": "20" }, - "t_contract(IWiseOffRamperRegistrationProcessor)21144": { + "t_contract(IWiseOffRamperRegistrationProcessor)6392": { "encoding": "inplace", "label": "contract IWiseOffRamperRegistrationProcessor", "numberOfBytes": "20" }, - "t_mapping(t_address,t_struct(AccountInfo)21084_storage)": { + "t_mapping(t_address,t_struct(AccountInfo)6332_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct IWiseAccountRegistry.AccountInfo)", "numberOfBytes": "32", - "value": "t_struct(AccountInfo)21084_storage" + "value": "t_struct(AccountInfo)6332_storage" }, "t_mapping(t_bytes32,t_bool)": { "encoding": "mapping", @@ -900,26 +905,26 @@ "numberOfBytes": "32", "value": "t_bool" }, - "t_mapping(t_bytes32,t_struct(AllowList)18041_storage)": { + "t_mapping(t_bytes32,t_struct(AllowList)3324_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct WiseAccountRegistry.AllowList)", "numberOfBytes": "32", - "value": "t_struct(AllowList)18041_storage" + "value": "t_struct(AllowList)3324_storage" }, - "t_mapping(t_bytes32,t_struct(DenyList)18031_storage)": { + "t_mapping(t_bytes32,t_struct(DenyList)3314_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct WiseAccountRegistry.DenyList)", "numberOfBytes": "32", - "value": "t_struct(DenyList)18031_storage" + "value": "t_struct(DenyList)3314_storage" }, - "t_struct(AccountInfo)21084_storage": { + "t_struct(AccountInfo)6332_storage": { "encoding": "inplace", "label": "struct IWiseAccountRegistry.AccountInfo", "members": [ { - "astId": 21079, + "astId": 6327, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "accountId", "offset": 0, @@ -927,7 +932,7 @@ "type": "t_bytes32" }, { - "astId": 21081, + "astId": 6329, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "offRampId", "offset": 0, @@ -935,7 +940,7 @@ "type": "t_bytes32" }, { - "astId": 21083, + "astId": 6331, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "wiseTagHash", "offset": 0, @@ -945,12 +950,12 @@ ], "numberOfBytes": "96" }, - "t_struct(AllowList)18041_storage": { + "t_struct(AllowList)3324_storage": { "encoding": "inplace", "label": "struct WiseAccountRegistry.AllowList", "members": [ { - "astId": 18033, + "astId": 3316, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "isEnabled", "offset": 0, @@ -958,7 +963,7 @@ "type": "t_bool" }, { - "astId": 18036, + "astId": 3319, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "allowedUsers", "offset": 0, @@ -966,7 +971,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 18040, + "astId": 3323, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "isAllowed", "offset": 0, @@ -976,12 +981,12 @@ ], "numberOfBytes": "96" }, - "t_struct(DenyList)18031_storage": { + "t_struct(DenyList)3314_storage": { "encoding": "inplace", "label": "struct WiseAccountRegistry.DenyList", "members": [ { - "astId": 18026, + "astId": 3309, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "deniedUsers", "offset": 0, @@ -989,7 +994,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 18030, + "astId": 3313, "contract": "contracts/ramps/wise/WiseAccountRegistry.sol:WiseAccountRegistry", "label": "isDenied", "offset": 0, diff --git a/contracts/deployments/sepolia/WiseOffRamperRegistrationProcessor.json b/contracts/deployments/sepolia/WiseOffRamperRegistrationProcessor.json index 4291969b3..c12f3c68b 100644 --- a/contracts/deployments/sepolia/WiseOffRamperRegistrationProcessor.json +++ b/contracts/deployments/sepolia/WiseOffRamperRegistrationProcessor.json @@ -1,5 +1,5 @@ { - "address": "0xEF14b8a0196002dA629c1eC585371274FA9Da7d8", + "address": "0xFEce1C61744646609B1EE8617b3c2B7221F7E336", "abi": [ { "inputs": [ @@ -163,7 +163,7 @@ "type": "tuple" } ], - "name": "processOffRamperProof", + "name": "processProof", "outputs": [ { "internalType": "bytes32", @@ -176,7 +176,7 @@ "type": "bytes32" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { @@ -265,39 +265,39 @@ "type": "function" } ], - "transactionHash": "0xbb38115b301ca363807758bf3b9bde6174aab824ccecf2c09baab049fbc74355", + "transactionHash": "0xf24e56e5378abb9e2dc586ed6a86b68d970f32188f2a1ae3e3101920ed7885ba", "receipt": { "to": null, "from": "0x4e39cF8578698131c57404e8bc3eEC820EDa51d8", - "contractAddress": "0xEF14b8a0196002dA629c1eC585371274FA9Da7d8", - "transactionIndex": 84, - "gasUsed": "1551436", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000001000000000000000000000000000000000000030000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000100000000000200000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x0be522a228e8d8ce97a6386591e66548de621ec9b336e324d6415bc19f57ca71", - "transactionHash": "0xbb38115b301ca363807758bf3b9bde6174aab824ccecf2c09baab049fbc74355", + "contractAddress": "0xFEce1C61744646609B1EE8617b3c2B7221F7E336", + "transactionIndex": 37, + "gasUsed": "1449900", + "logsBloom": "0x00000000000000000000000000010000000000000000000000800000000000040000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000100000000000000000000000000000000000000000000000000000000000000000008000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x6dae84f996306ae046d447ed4cd6452e01c2c09bb28bd2ab55bfa37a99143a99", + "transactionHash": "0xf24e56e5378abb9e2dc586ed6a86b68d970f32188f2a1ae3e3101920ed7885ba", "logs": [ { - "transactionIndex": 84, - "blockNumber": 5574197, - "transactionHash": "0xbb38115b301ca363807758bf3b9bde6174aab824ccecf2c09baab049fbc74355", - "address": "0xEF14b8a0196002dA629c1eC585371274FA9Da7d8", + "transactionIndex": 37, + "blockNumber": 5635195, + "transactionHash": "0xf24e56e5378abb9e2dc586ed6a86b68d970f32188f2a1ae3e3101920ed7885ba", + "address": "0xFEce1C61744646609B1EE8617b3c2B7221F7E336", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000004e39cf8578698131c57404e8bc3eec820eda51d8" ], "data": "0x", - "logIndex": 77, - "blockHash": "0x0be522a228e8d8ce97a6386591e66548de621ec9b336e324d6415bc19f57ca71" + "logIndex": 58, + "blockHash": "0x6dae84f996306ae046d447ed4cd6452e01c2c09bb28bd2ab55bfa37a99143a99" } ], - "blockNumber": 5574197, - "cumulativeGasUsed": "8509712", + "blockNumber": 5635195, + "cumulativeGasUsed": "7022486", "status": 1, "byzantium": true }, "args": [ - "0x7eDD66B19A22293af86A2d96761FD7146BA3fF6c", + "0xF44B36992B96043128A3240744Bfe9b070a098Fa", "0x166338393593e85bfde8B65358Ec5801A3445D12", "0xAf0196f22a1383B779E3f833AD35BFf38722c8AD", "0", @@ -305,10 +305,10 @@ "wise.com" ], "numDeployments": 1, - "solcInputHash": "6e4c0155cf194d54974389502ced73c2", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_ramp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"},{\"internalType\":\"contract INullifierRegistry\",\"name\":\"_nullifierRegistry\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_host\",\"type\":\"string\"}],\"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\":false,\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"}],\"name\":\"VerifierSigningKeySet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"endpoint\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"host\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nullifierRegistry\",\"outputs\":[{\"internalType\":\"contract INullifierRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"profileId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"mcAccountId\",\"type\":\"string\"}],\"internalType\":\"struct IWiseOffRamperRegistrationProcessor.OffRamperRegistrationData\",\"name\":\"public_values\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"internalType\":\"struct IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof\",\"name\":\"_proof\",\"type\":\"tuple\"}],\"name\":\"processOffRamperProof\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"onRampId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"offRampId\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ramp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"}],\"name\":\"setTimestampBuffer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"}],\"name\":\"setVerifierSigningKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timestampBuffer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verifierSigningKey\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setTimestampBuffer(uint256)\":{\"params\":{\"_timestampBuffer\":\"The timestamp buffer for validated TLS calls\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"setTimestampBuffer(uint256)\":{\"notice\":\"ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2 timestamps.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ramps/wise/WiseOffRamperRegistrationProcessor.sol\":\"WiseOffRamperRegistrationProcessor\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"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/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/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"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\"},\"contracts/lib/StringConversionUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\n// Building on zk-email's StringUtils library we add the ability to handle decimals when\\n// converting from string to Uint\\nlibrary StringConversionUtils {\\n \\n /**\\n * @notice Function that parses numbers returned as strings including floating point numbers. Returned floating point\\n * numbers are to have the desired amount of decimal specified. If the stringified version of the floating point\\n * number has more decimal places than desired then the function will revert in order to be maximally safe. If\\n * the returned number has multiple floating points then the function will revert.\\n *\\n * Examples: _s = \\\"12.34\\\", _expectedDecimals = 6 => 12340000\\n * _s = \\\"12.34\\\", _expectedDecimals = 2 => 1234\\n * _s = \\\"12.34\\\", _expectedDecimals = 1 => REVERT (we never want loss of precision only addition)\\n * _s = \\\"12.34.56\\\", _expectedDecimals = 6 => REVERT (Invalid number)\\n *\\n * @param _s String being processed\\n * @param _desiredDecimals Desired amount of decimal places\\n */\\n function stringToUint(string memory _s, uint256 _desiredDecimals) internal pure returns (uint256) {\\n return stringToUint(_s, 0x2E, _desiredDecimals);\\n }\\n\\n function stringToUint(\\n string memory _s,\\n bytes1 _decimalCharacter,\\n uint256 _desiredDecimals\\n )\\n internal\\n pure\\n returns (uint256)\\n {\\n bytes memory b = bytes(_s);\\n\\n uint256 result = 0;\\n uint256 decimalPlaces = 0;\\n\\n bool decimals = false;\\n for (uint256 i = 0; i < b.length; i++) {\\n if (b[i] >= 0x30 && b[i] <= 0x39) {\\n result = result * 10 + (uint256(uint8(b[i])) - 48);\\n }\\n\\n if (decimals) {\\n decimalPlaces++;\\n }\\n\\n if (b[i] == _decimalCharacter) {\\n require(decimals == false, \\\"String has multiple decimals\\\");\\n decimals = true;\\n }\\n }\\n\\n require(decimalPlaces <= _desiredDecimals, \\\"String has too many decimal places\\\");\\n return result * (10 ** (_desiredDecimals - decimalPlaces));\\n }\\n\\n /**\\n * @notice Function that returns a substring from _startIndex to _endIndex (non-inclusive).\\n *\\n * @param _str String being processed\\n * @param _startIndex Index to start parsing from\\n * @param _endIndex Index to stop parsing at (index not included in result)\\n */\\n function substring(string memory _str, uint _startIndex, uint _endIndex) internal pure returns (string memory ) {\\n bytes memory strBytes = bytes(_str);\\n bytes memory result = new bytes(_endIndex-_startIndex);\\n for(uint i = _startIndex; i < _endIndex; i++) {\\n result[i-_startIndex] = strBytes[i];\\n }\\n return string(result);\\n }\\n\\n function replaceString(\\n string memory _str,\\n string memory _lookupValue,\\n string memory _replaceValue\\n )\\n internal\\n pure\\n returns (string memory)\\n {\\n bytes memory strBytes = bytes(_str);\\n bytes memory lookupBytes = bytes(_lookupValue);\\n\\n uint256 lookupIndex = indexOf(_str, _lookupValue);\\n if (lookupIndex == type(uint256).max) {\\n return _str;\\n }\\n\\n // Split the original string into two parts: before and after the keyword\\n string memory beforeKeyword = substring(_str, 0, lookupIndex);\\n string memory afterKeyword = substring(_str, lookupIndex + lookupBytes.length, strBytes.length);\\n \\n return string.concat(beforeKeyword, _replaceValue, afterKeyword);\\n }\\n\\n function indexOf(string memory str, string memory substr) internal pure returns (uint) {\\n bytes memory strBytes = bytes(str);\\n bytes memory substrBytes = bytes(substr);\\n \\n if (strBytes.length < substrBytes.length) return type(uint256).max;\\n \\n for (uint i = 0; i <= strBytes.length - substrBytes.length; i++) {\\n bool found = true;\\n for (uint j = 0; j < substrBytes.length; j++) {\\n if (strBytes[i + j] != substrBytes[j]) {\\n found = false;\\n break;\\n }\\n }\\n if (found) return i;\\n }\\n \\n return type(uint256).max;\\n }\\n\\n function stringComparison(string memory _a, string memory _b) internal pure returns (bool) {\\n return (keccak256(abi.encodePacked(_a)) == keccak256(abi.encodePacked(_b)));\\n }\\n}\\n\",\"keccak256\":\"0xfcdfb3c2c8d5a6b7f480f827049782a70fb98f8b3838dcad0e0bb95237b94a0c\",\"license\":\"MIT\"},\"contracts/processors/TLSBaseProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { ECDSA } from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { SignatureChecker } from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\n\\nimport { INullifierRegistry } from \\\"./nullifierRegistries/INullifierRegistry.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract TLSBaseProcessor is Ownable {\\n\\n using SignatureChecker for address;\\n using ECDSA for bytes32;\\n\\n /* ============ Modifiers ============ */\\n modifier onlyRamp() {\\n require(msg.sender == ramp, \\\"Only Ramp can call this function\\\");\\n _;\\n }\\n\\n /* ============ State Variables ============ */\\n address public immutable ramp;\\n string public endpoint;\\n string public host;\\n\\n INullifierRegistry public nullifierRegistry;\\n uint256 public timestampBuffer;\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _ramp,\\n INullifierRegistry _nullifierRegistry,\\n uint256 _timestampBuffer,\\n string memory _endpoint,\\n string memory _host\\n )\\n Ownable()\\n {\\n ramp = _ramp;\\n endpoint = _endpoint;\\n host = _host;\\n\\n nullifierRegistry = _nullifierRegistry;\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ External Functions ============ */\\n\\n /**\\n * @notice ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds\\n * that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2\\n * timestamps.\\n *\\n * @param _timestampBuffer The timestamp buffer for validated TLS calls\\n */\\n function setTimestampBuffer(uint256 _timestampBuffer) external onlyOwner {\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ Internal Functions ============ */\\n\\n function _validateTLSEndpoint(\\n string memory _expectedEndpoint,\\n string memory _passedEndpoint\\n )\\n internal\\n pure\\n {\\n require(\\n keccak256(abi.encode(_expectedEndpoint)) == keccak256(abi.encode(_passedEndpoint)),\\n \\\"Endpoint does not match expected\\\"\\n );\\n }\\n\\n function _validateTLSHost(\\n string memory _expectedHost,\\n string memory _passedHost\\n )\\n internal\\n pure\\n {\\n require(\\n keccak256(abi.encode(_expectedHost)) == keccak256(abi.encode(_passedHost)),\\n \\\"Host does not match expected\\\"\\n );\\n }\\n\\n function _validateAndAddNullifier(bytes32 _nullifier) internal {\\n require(!nullifierRegistry.isNullified(_nullifier), \\\"Nullifier has already been used\\\");\\n nullifierRegistry.addNullifier(_nullifier);\\n }\\n\\n function _isValidVerifierSignature(\\n bytes memory _message,\\n bytes memory _signature,\\n address _verifier\\n )\\n internal\\n view\\n returns(bool)\\n {\\n bytes32 verifierPayload = keccak256(_message).toEthSignedMessageHash();\\n\\n return _verifier.isValidSignatureNow(verifierPayload, _signature);\\n }\\n}\\n\",\"keccak256\":\"0xbbdb8f203288645916ad04ee65625fae570ed091fbf243a706df7991b29ffe61\",\"license\":\"MIT\"},\"contracts/processors/nullifierRegistries/INullifierRegistry.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface INullifierRegistry {\\n function addNullifier(bytes32 _nullifier) external;\\n function isNullified(bytes32 _nullifier) external view returns(bool);\\n}\\n\",\"keccak256\":\"0x107164bc9a320938b513305878163b7fa884da4cdae58d0c8e81bfbb00c97c5e\",\"license\":\"MIT\"},\"contracts/ramps/wise/WiseOffRamperRegistrationProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { INullifierRegistry } from \\\"../../processors/nullifierRegistries/INullifierRegistry.sol\\\";\\nimport { IWiseOffRamperRegistrationProcessor } from \\\"./interfaces/IWiseOffRamperRegistrationProcessor.sol\\\";\\nimport { StringConversionUtils } from \\\"../../lib/StringConversionUtils.sol\\\";\\nimport { TLSBaseProcessor } from \\\"../../processors/TLSBaseProcessor.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract WiseOffRamperRegistrationProcessor is IWiseOffRamperRegistrationProcessor, TLSBaseProcessor {\\n\\n using StringConversionUtils for string;\\n \\n /* ============ Events ============ */\\n event VerifierSigningKeySet(address _verifierSigningKey);\\n \\n /* ============ Public Variables ============ */\\n address public verifierSigningKey;\\n \\n /* ============ Constructor ============ */\\n constructor(\\n address _ramp,\\n address _verifierSigningKey,\\n INullifierRegistry _nullifierRegistry,\\n uint256 _timestampBuffer,\\n string memory _endpoint,\\n string memory _host\\n )\\n TLSBaseProcessor(\\n _ramp,\\n _nullifierRegistry,\\n _timestampBuffer,\\n _endpoint,\\n _host\\n )\\n {\\n verifierSigningKey = _verifierSigningKey;\\n }\\n\\n /* ============ External Functions ============ */\\n\\n function processOffRamperProof(\\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof calldata _proof\\n )\\n public\\n override\\n onlyRamp\\n returns(bytes32 onRampId, bytes32 offRampId)\\n {\\n _validateProof(_proof.public_values, _proof.proof);\\n\\n _validateTLSEndpoint(endpoint.replaceString(\\\"*\\\", _proof.public_values.profileId), _proof.public_values.endpoint);\\n _validateTLSHost(host, _proof.public_values.host);\\n\\n _validateAndAddNullifier(keccak256(abi.encode(\\\"registration\\\", _proof.public_values.mcAccountId)));\\n\\n onRampId = bytes32(_proof.public_values.profileId.stringToUint(0));\\n offRampId = bytes32(_proof.public_values.mcAccountId.stringToUint(0));\\n }\\n\\n /* ============ External Admin Functions ============ */\\n\\n function setVerifierSigningKey(address _verifierSigningKey) external onlyOwner {\\n verifierSigningKey = _verifierSigningKey;\\n\\n emit VerifierSigningKeySet(_verifierSigningKey);\\n }\\n\\n /* ============ View Functions ============ */\\n\\n function verifyProof(\\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationData memory _publicValues, \\n bytes memory _proof\\n )\\n internal\\n view\\n returns(bool)\\n { \\n bytes memory encodedMessage = abi.encode(_publicValues.endpoint, _publicValues.host, _publicValues.profileId, _publicValues.mcAccountId);\\n return _isValidVerifierSignature(encodedMessage, _proof, verifierSigningKey);\\n }\\n\\n /* ============ Internal Functions ============ */\\n\\n function _validateProof(\\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationData memory _publicValues, \\n bytes memory _proof\\n )\\n internal\\n view\\n { \\n require(\\n verifyProof(_publicValues, _proof),\\n \\\"Invalid signature from verifier\\\"\\n );\\n }\\n}\\n\",\"keccak256\":\"0xe60491cebb9eac967ea2dab774e2263fe9b1cc8804217940659997c9a8aaf099\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseOffRamperRegistrationProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseOffRamperRegistrationProcessor {\\n\\n struct OffRamperRegistrationData {\\n string endpoint;\\n string host;\\n string profileId;\\n string mcAccountId;\\n }\\n\\n struct OffRamperRegistrationProof {\\n OffRamperRegistrationData public_values;\\n bytes proof;\\n }\\n\\n function processOffRamperProof(\\n OffRamperRegistrationProof calldata _proof\\n )\\n external\\n returns (bytes32, bytes32);\\n}\\n\",\"keccak256\":\"0x6461b64625b383ad3eb4c526d937413b23157f50262504c02187ed0556b036fb\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523480156200001157600080fd5b5060405162001bef38038062001bef8339810160408190526200003491620001e2565b85848484846200004433620000b4565b6001600160a01b03851660805260016200005f838262000324565b5060026200006e828262000324565b5050600380546001600160a01b039485166001600160a01b03199182161790915560049290925550600580549890921697169690961790955550620003f0945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200011a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200014557600080fd5b81516001600160401b03808211156200016257620001626200011d565b604051601f8301601f19908116603f011681019082821181831017156200018d576200018d6200011d565b81604052838152602092508683858801011115620001aa57600080fd5b600091505b83821015620001ce5785820183015181830184015290820190620001af565b600093810190920192909252949350505050565b60008060008060008060c08789031215620001fc57600080fd5b8651620002098162000104565b60208801519096506200021c8162000104565b60408801519095506200022f8162000104565b6060880151608089015191955093506001600160401b03808211156200025457600080fd5b620002628a838b0162000133565b935060a08901519150808211156200027957600080fd5b506200028889828a0162000133565b9150509295509295509295565b600181811c90821680620002aa57607f821691505b602082108103620002cb57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200031f57600081815260208120601f850160051c81016020861015620002fa5750805b601f850160051c820191505b818110156200031b5782815560010162000306565b5050505b505050565b81516001600160401b038111156200034057620003406200011d565b620003588162000351845462000295565b84620002d1565b602080601f831160018114620003905760008415620003775750858301515b600019600386901b1c1916600185901b1785556200031b565b600085815260208120601f198616915b82811015620003c157888601518255948401946001909101908401620003a0565b5085821015620003e05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516117dd620004126000396000818160ee015261023d01526117dd6000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80638da5cb5b116100715780638da5cb5b1461016a578063b2a3fda41461017b578063b870676c1461018e578063dbac5821146101a1578063f2fde38b146101b8578063f437bc59146101cb57600080fd5b80630fa4ed4d146100b957806315d276e1146100e95780634e06a32b14610110578063508c2093146101255780635e280f111461014d578063715018a614610162575b600080fd5b6005546100cc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100cc7f000000000000000000000000000000000000000000000000000000000000000081565b61012361011e3660046111c8565b6101d3565b005b6101386101333660046111f1565b61022f565b604080519283526020830191909152016100e0565b61015561060e565b6040516100e0919061127c565b61012361069c565b6000546001600160a01b03166100cc565b61012361018936600461128f565b6106b0565b6003546100cc906001600160a01b031681565b6101aa60045481565b6040519081526020016100e0565b6101236101c63660046111c8565b6106bd565b610155610736565b6101db610743565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fb8603ceabf8ee4633f1fd8c0ae9e0e64f2fc2fea5cb79a96c18efd007aab6f969060200160405180910390a150565b600080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102af5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792052616d702063616e2063616c6c20746869732066756e6374696f6e60448201526064015b60405180910390fd5b61030c6102bc84806112a8565b6102c590611394565b6102d2602086018661144b565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061079d92505050565b6040805180820190915260018152601560f91b6020820152610462906104149061033686806112a8565b61034490604081019061144b565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050600180549092506103879150611492565b80601f01602080910402602001604051908101604052809291908181526020018280546103b390611492565b80156104005780601f106103d557610100808354040283529160200191610400565b820191906000526020600020905b8154815290600101906020018083116103e357829003601f168201915b50505050506107f79092919063ffffffff16565b61041e85806112a8565b610428908061144b565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061087c92505050565b6105466002805461047290611492565b80601f016020809104026020016040519081016040528092919081815260200182805461049e90611492565b80156104eb5780601f106104c0576101008083540402835291602001916104eb565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b506104fe93508892508291506112a89050565b61050c90602081019061144b565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061091792505050565b61058d61055384806112a8565b61056190606081019061144b565b6040516020016105729291906114cc565b604051602081830303815290604052805190602001206109b2565b6105e7600061059c85806112a8565b6105aa90604081019061144b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293925050610acd9050565b915061060660006105f885806112a8565b6105aa90606081019061144b565b919391925050565b6001805461061b90611492565b80601f016020809104026020016040519081016040528092919081815260200182805461064790611492565b80156106945780601f1061066957610100808354040283529160200191610694565b820191906000526020600020905b81548152906001019060200180831161067757829003601f168201915b505050505081565b6106a4610743565b6106ae6000610ae7565b565b6106b8610743565b600455565b6106c5610743565b6001600160a01b03811661072a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102a6565b61073381610ae7565b50565b6002805461061b90611492565b6000546001600160a01b031633146106ae5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102a6565b6107a78282610b37565b6107f35760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e61747572652066726f6d2076657269666965720060448201526064016102a6565b5050565b6060838360006108078383610b95565b9050600019810361081d57869350505050610875565b600061082b88600084610c74565b90506000610847898551856108409190611534565b8751610c74565b905081878260405160200161085e93929190611547565b604051602081830303815290604052955050505050505b9392505050565b8060405160200161088d919061127c565b60405160208183030381529060405280519060200120826040516020016108b4919061127c565b60405160208183030381529060405280519060200120146107f35760405162461bcd60e51b815260206004820181905260248201527f456e64706f696e7420646f6573206e6f74206d6174636820657870656374656460448201526064016102a6565b80604051602001610928919061127c565b604051602081830303815290604052805190602001208260405160200161094f919061127c565b60405160208183030381529060405280519060200120146107f35760405162461bcd60e51b815260206004820152601c60248201527f486f737420646f6573206e6f74206d617463682065787065637465640000000060448201526064016102a6565b60035460405163169394bb60e01b8152600481018390526001600160a01b039091169063169394bb90602401602060405180830381865afa1580156109fb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1f919061158a565b15610a6c5760405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e20757365640060448201526064016102a6565b600354604051632dea6f9960e11b8152600481018390526001600160a01b0390911690635bd4df3290602401600060405180830381600087803b158015610ab257600080fd5b505af1158015610ac6573d6000803e3d6000fd5b5050505050565b6000610ade83601760f91b84610d41565b90505b92915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000808360000151846020015185604001518660600151604051602001610b6194939291906115ac565b60408051601f19818403018152919052600554909150610b8d90829085906001600160a01b0316610f1e565b949350505050565b80518251600091849184911115610bb25760001992505050610ae1565b60005b81518351610bc39190611604565b8111610c6757600160005b8351811015610c4257838181518110610be957610be9611617565b01602001516001600160f81b03191685610c038386611534565b81518110610c1357610c13611617565b01602001516001600160f81b03191614610c305760009150610c42565b80610c3a8161162d565b915050610bce565b508015610c5457509250610ae1915050565b5080610c5f8161162d565b915050610bb5565b5060001995945050505050565b6060836000610c838585611604565b67ffffffffffffffff811115610c9b57610c9b6112c8565b6040519080825280601f01601f191660200182016040528015610cc5576020820181803683370190505b509050845b84811015610d3757828181518110610ce457610ce4611617565b01602001516001600160f81b03191682610cfe8884611604565b81518110610d0e57610d0e611617565b60200101906001600160f81b031916908160001a90535080610d2f8161162d565b915050610cca565b5095945050505050565b600083818080805b8451811015610e9757603060f81b858281518110610d6957610d69611617565b01602001516001600160f81b03191610801590610daa5750603960f81b858281518110610d9857610d98611617565b01602001516001600160f81b03191611155b15610ded576030858281518110610dc357610dc3611617565b0160200151610dd5919060f81c611604565b610de085600a611646565b610dea9190611534565b93505b8115610e015782610dfd8161162d565b9350505b876001600160f81b031916858281518110610e1e57610e1e611617565b01602001516001600160f81b03191603610e85578115610e805760405162461bcd60e51b815260206004820152601c60248201527f537472696e6720686173206d756c7469706c6520646563696d616c730000000060448201526064016102a6565b600191505b80610e8f8161162d565b915050610d49565b5085821115610ef35760405162461bcd60e51b815260206004820152602260248201527f537472696e672068617320746f6f206d616e7920646563696d616c20706c6163604482015261657360f01b60648201526084016102a6565b610efd8287611604565b610f0890600a611741565b610f129084611646565b98975050505050505050565b825160208401207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c8120610f696001600160a01b0384168286610f72565b95945050505050565b6000806000610f818585610fd3565b90925090506000816004811115610f9a57610f9a61174d565b148015610fb85750856001600160a01b0316826001600160a01b0316145b80610fc95750610fc9868686611018565b9695505050505050565b60008082516041036110095760208301516040840151606085015160001a610ffd87828585611104565b94509450505050611011565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b8686604051602401611042929190611763565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051611080919061177c565b600060405180830381855afa9150503d80600081146110bb576040519150601f19603f3d011682016040523d82523d6000602084013e6110c0565b606091505b50915091508180156110d457506020815110155b8015610fc957508051630b135d3f60e11b906110f9908301602090810190840161178e565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561113b57506000905060036111bf565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561118f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166111b8576000600192509250506111bf565b9150600090505b94509492505050565b6000602082840312156111da57600080fd5b81356001600160a01b038116811461087557600080fd5b60006020828403121561120357600080fd5b813567ffffffffffffffff81111561121a57600080fd5b82016040818503121561087557600080fd5b60005b8381101561124757818101518382015260200161122f565b50506000910152565b6000815180845261126881602086016020860161122c565b601f01601f19169290920160200192915050565b602081526000610ade6020830184611250565b6000602082840312156112a157600080fd5b5035919050565b60008235607e198336030181126112be57600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715611301576113016112c8565b60405290565b600082601f83011261131857600080fd5b813567ffffffffffffffff80821115611333576113336112c8565b604051601f8301601f19908116603f0116810190828211818310171561135b5761135b6112c8565b8160405283815286602085880101111561137457600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000608082360312156113a657600080fd5b6113ae6112de565b823567ffffffffffffffff808211156113c657600080fd5b6113d236838701611307565b835260208501359150808211156113e857600080fd5b6113f436838701611307565b6020840152604085013591508082111561140d57600080fd5b61141936838701611307565b6040840152606085013591508082111561143257600080fd5b5061143f36828601611307565b60608301525092915050565b6000808335601e1984360301811261146257600080fd5b83018035915067ffffffffffffffff82111561147d57600080fd5b60200191503681900382131561101157600080fd5b600181811c908216806114a657607f821691505b6020821081036114c657634e487b7160e01b600052602260045260246000fd5b50919050565b60408152600c60408201526b3932b3b4b9ba3930ba34b7b760a11b606082015260806020820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ae157610ae161151e565b6000845161155981846020890161122c565b84519083019061156d81836020890161122c565b845191019061158081836020880161122c565b0195945050505050565b60006020828403121561159c57600080fd5b8151801515811461087557600080fd5b6080815260006115bf6080830187611250565b82810360208401526115d18187611250565b905082810360408401526115e58186611250565b905082810360608401526115f98185611250565b979650505050505050565b81810381811115610ae157610ae161151e565b634e487b7160e01b600052603260045260246000fd5b60006001820161163f5761163f61151e565b5060010190565b8082028115828204841417610ae157610ae161151e565b600181815b8085111561169857816000190482111561167e5761167e61151e565b8085161561168b57918102915b93841c9390800290611662565b509250929050565b6000826116af57506001610ae1565b816116bc57506000610ae1565b81600181146116d257600281146116dc576116f8565b6001915050610ae1565b60ff8411156116ed576116ed61151e565b50506001821b610ae1565b5060208310610133831016604e8410600b841016171561171b575081810a610ae1565b611725838361165d565b80600019048211156117395761173961151e565b029392505050565b6000610ade83836116a0565b634e487b7160e01b600052602160045260246000fd5b828152604060208201526000610b8d6040830184611250565b600082516112be81846020870161122c565b6000602082840312156117a057600080fd5b505191905056fea26469706673582212209bd88da358d8a452c60dda410dfb545d485aa5b27207d0c9e48e5fc09a20a22364736f6c63430008120033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80638da5cb5b116100715780638da5cb5b1461016a578063b2a3fda41461017b578063b870676c1461018e578063dbac5821146101a1578063f2fde38b146101b8578063f437bc59146101cb57600080fd5b80630fa4ed4d146100b957806315d276e1146100e95780634e06a32b14610110578063508c2093146101255780635e280f111461014d578063715018a614610162575b600080fd5b6005546100cc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100cc7f000000000000000000000000000000000000000000000000000000000000000081565b61012361011e3660046111c8565b6101d3565b005b6101386101333660046111f1565b61022f565b604080519283526020830191909152016100e0565b61015561060e565b6040516100e0919061127c565b61012361069c565b6000546001600160a01b03166100cc565b61012361018936600461128f565b6106b0565b6003546100cc906001600160a01b031681565b6101aa60045481565b6040519081526020016100e0565b6101236101c63660046111c8565b6106bd565b610155610736565b6101db610743565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fb8603ceabf8ee4633f1fd8c0ae9e0e64f2fc2fea5cb79a96c18efd007aab6f969060200160405180910390a150565b600080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102af5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792052616d702063616e2063616c6c20746869732066756e6374696f6e60448201526064015b60405180910390fd5b61030c6102bc84806112a8565b6102c590611394565b6102d2602086018661144b565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061079d92505050565b6040805180820190915260018152601560f91b6020820152610462906104149061033686806112a8565b61034490604081019061144b565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050600180549092506103879150611492565b80601f01602080910402602001604051908101604052809291908181526020018280546103b390611492565b80156104005780601f106103d557610100808354040283529160200191610400565b820191906000526020600020905b8154815290600101906020018083116103e357829003601f168201915b50505050506107f79092919063ffffffff16565b61041e85806112a8565b610428908061144b565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061087c92505050565b6105466002805461047290611492565b80601f016020809104026020016040519081016040528092919081815260200182805461049e90611492565b80156104eb5780601f106104c0576101008083540402835291602001916104eb565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b506104fe93508892508291506112a89050565b61050c90602081019061144b565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061091792505050565b61058d61055384806112a8565b61056190606081019061144b565b6040516020016105729291906114cc565b604051602081830303815290604052805190602001206109b2565b6105e7600061059c85806112a8565b6105aa90604081019061144b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293925050610acd9050565b915061060660006105f885806112a8565b6105aa90606081019061144b565b919391925050565b6001805461061b90611492565b80601f016020809104026020016040519081016040528092919081815260200182805461064790611492565b80156106945780601f1061066957610100808354040283529160200191610694565b820191906000526020600020905b81548152906001019060200180831161067757829003601f168201915b505050505081565b6106a4610743565b6106ae6000610ae7565b565b6106b8610743565b600455565b6106c5610743565b6001600160a01b03811661072a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102a6565b61073381610ae7565b50565b6002805461061b90611492565b6000546001600160a01b031633146106ae5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102a6565b6107a78282610b37565b6107f35760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e61747572652066726f6d2076657269666965720060448201526064016102a6565b5050565b6060838360006108078383610b95565b9050600019810361081d57869350505050610875565b600061082b88600084610c74565b90506000610847898551856108409190611534565b8751610c74565b905081878260405160200161085e93929190611547565b604051602081830303815290604052955050505050505b9392505050565b8060405160200161088d919061127c565b60405160208183030381529060405280519060200120826040516020016108b4919061127c565b60405160208183030381529060405280519060200120146107f35760405162461bcd60e51b815260206004820181905260248201527f456e64706f696e7420646f6573206e6f74206d6174636820657870656374656460448201526064016102a6565b80604051602001610928919061127c565b604051602081830303815290604052805190602001208260405160200161094f919061127c565b60405160208183030381529060405280519060200120146107f35760405162461bcd60e51b815260206004820152601c60248201527f486f737420646f6573206e6f74206d617463682065787065637465640000000060448201526064016102a6565b60035460405163169394bb60e01b8152600481018390526001600160a01b039091169063169394bb90602401602060405180830381865afa1580156109fb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1f919061158a565b15610a6c5760405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e20757365640060448201526064016102a6565b600354604051632dea6f9960e11b8152600481018390526001600160a01b0390911690635bd4df3290602401600060405180830381600087803b158015610ab257600080fd5b505af1158015610ac6573d6000803e3d6000fd5b5050505050565b6000610ade83601760f91b84610d41565b90505b92915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000808360000151846020015185604001518660600151604051602001610b6194939291906115ac565b60408051601f19818403018152919052600554909150610b8d90829085906001600160a01b0316610f1e565b949350505050565b80518251600091849184911115610bb25760001992505050610ae1565b60005b81518351610bc39190611604565b8111610c6757600160005b8351811015610c4257838181518110610be957610be9611617565b01602001516001600160f81b03191685610c038386611534565b81518110610c1357610c13611617565b01602001516001600160f81b03191614610c305760009150610c42565b80610c3a8161162d565b915050610bce565b508015610c5457509250610ae1915050565b5080610c5f8161162d565b915050610bb5565b5060001995945050505050565b6060836000610c838585611604565b67ffffffffffffffff811115610c9b57610c9b6112c8565b6040519080825280601f01601f191660200182016040528015610cc5576020820181803683370190505b509050845b84811015610d3757828181518110610ce457610ce4611617565b01602001516001600160f81b03191682610cfe8884611604565b81518110610d0e57610d0e611617565b60200101906001600160f81b031916908160001a90535080610d2f8161162d565b915050610cca565b5095945050505050565b600083818080805b8451811015610e9757603060f81b858281518110610d6957610d69611617565b01602001516001600160f81b03191610801590610daa5750603960f81b858281518110610d9857610d98611617565b01602001516001600160f81b03191611155b15610ded576030858281518110610dc357610dc3611617565b0160200151610dd5919060f81c611604565b610de085600a611646565b610dea9190611534565b93505b8115610e015782610dfd8161162d565b9350505b876001600160f81b031916858281518110610e1e57610e1e611617565b01602001516001600160f81b03191603610e85578115610e805760405162461bcd60e51b815260206004820152601c60248201527f537472696e6720686173206d756c7469706c6520646563696d616c730000000060448201526064016102a6565b600191505b80610e8f8161162d565b915050610d49565b5085821115610ef35760405162461bcd60e51b815260206004820152602260248201527f537472696e672068617320746f6f206d616e7920646563696d616c20706c6163604482015261657360f01b60648201526084016102a6565b610efd8287611604565b610f0890600a611741565b610f129084611646565b98975050505050505050565b825160208401207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c8120610f696001600160a01b0384168286610f72565b95945050505050565b6000806000610f818585610fd3565b90925090506000816004811115610f9a57610f9a61174d565b148015610fb85750856001600160a01b0316826001600160a01b0316145b80610fc95750610fc9868686611018565b9695505050505050565b60008082516041036110095760208301516040840151606085015160001a610ffd87828585611104565b94509450505050611011565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b8686604051602401611042929190611763565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051611080919061177c565b600060405180830381855afa9150503d80600081146110bb576040519150601f19603f3d011682016040523d82523d6000602084013e6110c0565b606091505b50915091508180156110d457506020815110155b8015610fc957508051630b135d3f60e11b906110f9908301602090810190840161178e565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561113b57506000905060036111bf565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561118f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166111b8576000600192509250506111bf565b9150600090505b94509492505050565b6000602082840312156111da57600080fd5b81356001600160a01b038116811461087557600080fd5b60006020828403121561120357600080fd5b813567ffffffffffffffff81111561121a57600080fd5b82016040818503121561087557600080fd5b60005b8381101561124757818101518382015260200161122f565b50506000910152565b6000815180845261126881602086016020860161122c565b601f01601f19169290920160200192915050565b602081526000610ade6020830184611250565b6000602082840312156112a157600080fd5b5035919050565b60008235607e198336030181126112be57600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715611301576113016112c8565b60405290565b600082601f83011261131857600080fd5b813567ffffffffffffffff80821115611333576113336112c8565b604051601f8301601f19908116603f0116810190828211818310171561135b5761135b6112c8565b8160405283815286602085880101111561137457600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000608082360312156113a657600080fd5b6113ae6112de565b823567ffffffffffffffff808211156113c657600080fd5b6113d236838701611307565b835260208501359150808211156113e857600080fd5b6113f436838701611307565b6020840152604085013591508082111561140d57600080fd5b61141936838701611307565b6040840152606085013591508082111561143257600080fd5b5061143f36828601611307565b60608301525092915050565b6000808335601e1984360301811261146257600080fd5b83018035915067ffffffffffffffff82111561147d57600080fd5b60200191503681900382131561101157600080fd5b600181811c908216806114a657607f821691505b6020821081036114c657634e487b7160e01b600052602260045260246000fd5b50919050565b60408152600c60408201526b3932b3b4b9ba3930ba34b7b760a11b606082015260806020820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ae157610ae161151e565b6000845161155981846020890161122c565b84519083019061156d81836020890161122c565b845191019061158081836020880161122c565b0195945050505050565b60006020828403121561159c57600080fd5b8151801515811461087557600080fd5b6080815260006115bf6080830187611250565b82810360208401526115d18187611250565b905082810360408401526115e58186611250565b905082810360608401526115f98185611250565b979650505050505050565b81810381811115610ae157610ae161151e565b634e487b7160e01b600052603260045260246000fd5b60006001820161163f5761163f61151e565b5060010190565b8082028115828204841417610ae157610ae161151e565b600181815b8085111561169857816000190482111561167e5761167e61151e565b8085161561168b57918102915b93841c9390800290611662565b509250929050565b6000826116af57506001610ae1565b816116bc57506000610ae1565b81600181146116d257600281146116dc576116f8565b6001915050610ae1565b60ff8411156116ed576116ed61151e565b50506001821b610ae1565b5060208310610133831016604e8410600b841016171561171b575081810a610ae1565b611725838361165d565b80600019048211156117395761173961151e565b029392505050565b6000610ade83836116a0565b634e487b7160e01b600052602160045260246000fd5b828152604060208201526000610b8d6040830184611250565b600082516112be81846020870161122c565b6000602082840312156117a057600080fd5b505191905056fea26469706673582212209bd88da358d8a452c60dda410dfb545d485aa5b27207d0c9e48e5fc09a20a22364736f6c63430008120033", + "solcInputHash": "0de631e329f560f49e3d6a21d19a30cc", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_ramp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"},{\"internalType\":\"contract INullifierRegistry\",\"name\":\"_nullifierRegistry\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_host\",\"type\":\"string\"}],\"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\":false,\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"}],\"name\":\"VerifierSigningKeySet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"endpoint\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"host\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nullifierRegistry\",\"outputs\":[{\"internalType\":\"contract INullifierRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"profileId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"mcAccountId\",\"type\":\"string\"}],\"internalType\":\"struct IWiseOffRamperRegistrationProcessor.OffRamperRegistrationData\",\"name\":\"public_values\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"internalType\":\"struct IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof\",\"name\":\"_proof\",\"type\":\"tuple\"}],\"name\":\"processProof\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"onRampId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"offRampId\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ramp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"}],\"name\":\"setTimestampBuffer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"}],\"name\":\"setVerifierSigningKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timestampBuffer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verifierSigningKey\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setTimestampBuffer(uint256)\":{\"params\":{\"_timestampBuffer\":\"The timestamp buffer for validated TLS calls\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"setTimestampBuffer(uint256)\":{\"notice\":\"ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2 timestamps.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ramps/wise/WiseOffRamperRegistrationProcessor.sol\":\"WiseOffRamperRegistrationProcessor\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"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/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/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"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\"},\"contracts/lib/StringConversionUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\n// Building on zk-email's StringUtils library we add the ability to handle decimals when\\n// converting from string to Uint\\nlibrary StringConversionUtils {\\n \\n /**\\n * @notice Function that parses numbers returned as strings including floating point numbers. Returned floating point\\n * numbers are to have the desired amount of decimal specified. If the stringified version of the floating point\\n * number has more decimal places than desired then the function will revert in order to be maximally safe. If\\n * the returned number has multiple floating points then the function will revert.\\n *\\n * Examples: _s = \\\"12.34\\\", _expectedDecimals = 6 => 12340000\\n * _s = \\\"12.34\\\", _expectedDecimals = 2 => 1234\\n * _s = \\\"12.34\\\", _expectedDecimals = 1 => REVERT (we never want loss of precision only addition)\\n * _s = \\\"12.34.56\\\", _expectedDecimals = 6 => REVERT (Invalid number)\\n *\\n * @param _s String being processed\\n * @param _desiredDecimals Desired amount of decimal places\\n */\\n function stringToUint(string memory _s, uint256 _desiredDecimals) internal pure returns (uint256) {\\n return stringToUint(_s, 0x2E, _desiredDecimals);\\n }\\n\\n function stringToUint(\\n string memory _s,\\n bytes1 _decimalCharacter,\\n uint256 _desiredDecimals\\n )\\n internal\\n pure\\n returns (uint256)\\n {\\n bytes memory b = bytes(_s);\\n\\n uint256 result = 0;\\n uint256 decimalPlaces = 0;\\n\\n bool decimals = false;\\n for (uint256 i = 0; i < b.length; i++) {\\n if (b[i] >= 0x30 && b[i] <= 0x39) {\\n result = result * 10 + (uint256(uint8(b[i])) - 48);\\n }\\n\\n if (decimals) {\\n decimalPlaces++;\\n }\\n\\n if (b[i] == _decimalCharacter) {\\n require(decimals == false, \\\"String has multiple decimals\\\");\\n decimals = true;\\n }\\n }\\n\\n require(decimalPlaces <= _desiredDecimals, \\\"String has too many decimal places\\\");\\n return result * (10 ** (_desiredDecimals - decimalPlaces));\\n }\\n\\n /**\\n * @notice Function that returns a substring from _startIndex to _endIndex (non-inclusive).\\n *\\n * @param _str String being processed\\n * @param _startIndex Index to start parsing from\\n * @param _endIndex Index to stop parsing at (index not included in result)\\n */\\n function substring(string memory _str, uint _startIndex, uint _endIndex) internal pure returns (string memory ) {\\n bytes memory strBytes = bytes(_str);\\n bytes memory result = new bytes(_endIndex-_startIndex);\\n for(uint i = _startIndex; i < _endIndex; i++) {\\n result[i-_startIndex] = strBytes[i];\\n }\\n return string(result);\\n }\\n\\n function replaceString(\\n string memory _str,\\n string memory _lookupValue,\\n string memory _replaceValue\\n )\\n internal\\n pure\\n returns (string memory)\\n {\\n bytes memory strBytes = bytes(_str);\\n bytes memory lookupBytes = bytes(_lookupValue);\\n\\n uint256 lookupIndex = indexOf(_str, _lookupValue);\\n if (lookupIndex == type(uint256).max) {\\n return _str;\\n }\\n\\n // Split the original string into two parts: before and after the keyword\\n string memory beforeKeyword = substring(_str, 0, lookupIndex);\\n string memory afterKeyword = substring(_str, lookupIndex + lookupBytes.length, strBytes.length);\\n \\n return string.concat(beforeKeyword, _replaceValue, afterKeyword);\\n }\\n\\n function indexOf(string memory str, string memory substr) internal pure returns (uint) {\\n bytes memory strBytes = bytes(str);\\n bytes memory substrBytes = bytes(substr);\\n \\n if (strBytes.length < substrBytes.length) return type(uint256).max;\\n \\n for (uint i = 0; i <= strBytes.length - substrBytes.length; i++) {\\n bool found = true;\\n for (uint j = 0; j < substrBytes.length; j++) {\\n if (strBytes[i + j] != substrBytes[j]) {\\n found = false;\\n break;\\n }\\n }\\n if (found) return i;\\n }\\n \\n return type(uint256).max;\\n }\\n\\n function stringComparison(string memory _a, string memory _b) internal pure returns (bool) {\\n return (keccak256(abi.encodePacked(_a)) == keccak256(abi.encodePacked(_b)));\\n }\\n}\\n\",\"keccak256\":\"0xfcdfb3c2c8d5a6b7f480f827049782a70fb98f8b3838dcad0e0bb95237b94a0c\",\"license\":\"MIT\"},\"contracts/processors/TLSBaseProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { ECDSA } from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { SignatureChecker } from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\n\\nimport { INullifierRegistry } from \\\"./nullifierRegistries/INullifierRegistry.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract TLSBaseProcessor is Ownable {\\n\\n using SignatureChecker for address;\\n using ECDSA for bytes32;\\n\\n /* ============ Modifiers ============ */\\n modifier onlyRamp() {\\n require(msg.sender == ramp, \\\"Only Ramp can call this function\\\");\\n _;\\n }\\n\\n /* ============ State Variables ============ */\\n address public immutable ramp;\\n string public endpoint;\\n string public host;\\n\\n INullifierRegistry public nullifierRegistry;\\n uint256 public timestampBuffer;\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _ramp,\\n INullifierRegistry _nullifierRegistry,\\n uint256 _timestampBuffer,\\n string memory _endpoint,\\n string memory _host\\n )\\n Ownable()\\n {\\n ramp = _ramp;\\n endpoint = _endpoint;\\n host = _host;\\n\\n nullifierRegistry = _nullifierRegistry;\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ External Functions ============ */\\n\\n /**\\n * @notice ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds\\n * that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2\\n * timestamps.\\n *\\n * @param _timestampBuffer The timestamp buffer for validated TLS calls\\n */\\n function setTimestampBuffer(uint256 _timestampBuffer) external onlyOwner {\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ Internal Functions ============ */\\n\\n function _validateTLSEndpoint(\\n string memory _expectedEndpoint,\\n string memory _passedEndpoint\\n )\\n internal\\n pure\\n {\\n require(\\n keccak256(abi.encode(_expectedEndpoint)) == keccak256(abi.encode(_passedEndpoint)),\\n \\\"Endpoint does not match expected\\\"\\n );\\n }\\n\\n function _validateTLSHost(\\n string memory _expectedHost,\\n string memory _passedHost\\n )\\n internal\\n pure\\n {\\n require(\\n keccak256(abi.encode(_expectedHost)) == keccak256(abi.encode(_passedHost)),\\n \\\"Host does not match expected\\\"\\n );\\n }\\n\\n function _validateAndAddNullifier(bytes32 _nullifier) internal {\\n require(!nullifierRegistry.isNullified(_nullifier), \\\"Nullifier has already been used\\\");\\n nullifierRegistry.addNullifier(_nullifier);\\n }\\n\\n function _isValidVerifierSignature(\\n bytes memory _message,\\n bytes memory _signature,\\n address _verifier\\n )\\n internal\\n view\\n returns(bool)\\n {\\n bytes32 verifierPayload = keccak256(_message).toEthSignedMessageHash();\\n\\n return _verifier.isValidSignatureNow(verifierPayload, _signature);\\n }\\n}\\n\",\"keccak256\":\"0xbbdb8f203288645916ad04ee65625fae570ed091fbf243a706df7991b29ffe61\",\"license\":\"MIT\"},\"contracts/processors/nullifierRegistries/INullifierRegistry.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface INullifierRegistry {\\n function addNullifier(bytes32 _nullifier) external;\\n function isNullified(bytes32 _nullifier) external view returns(bool);\\n}\\n\",\"keccak256\":\"0x107164bc9a320938b513305878163b7fa884da4cdae58d0c8e81bfbb00c97c5e\",\"license\":\"MIT\"},\"contracts/ramps/wise/WiseOffRamperRegistrationProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { INullifierRegistry } from \\\"../../processors/nullifierRegistries/INullifierRegistry.sol\\\";\\nimport { IWiseOffRamperRegistrationProcessor } from \\\"./interfaces/IWiseOffRamperRegistrationProcessor.sol\\\";\\nimport { StringConversionUtils } from \\\"../../lib/StringConversionUtils.sol\\\";\\nimport { TLSBaseProcessor } from \\\"../../processors/TLSBaseProcessor.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract WiseOffRamperRegistrationProcessor is IWiseOffRamperRegistrationProcessor, TLSBaseProcessor {\\n\\n using StringConversionUtils for string;\\n \\n /* ============ Events ============ */\\n event VerifierSigningKeySet(address _verifierSigningKey);\\n \\n /* ============ Public Variables ============ */\\n address public verifierSigningKey;\\n \\n /* ============ Constructor ============ */\\n constructor(\\n address _ramp,\\n address _verifierSigningKey,\\n INullifierRegistry _nullifierRegistry,\\n uint256 _timestampBuffer,\\n string memory _endpoint,\\n string memory _host\\n )\\n TLSBaseProcessor(\\n _ramp,\\n _nullifierRegistry,\\n _timestampBuffer,\\n _endpoint,\\n _host\\n )\\n {\\n verifierSigningKey = _verifierSigningKey;\\n }\\n\\n /* ============ External Functions ============ */\\n\\n function processProof(\\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof calldata _proof\\n )\\n public\\n view\\n override\\n onlyRamp\\n returns(bytes32 onRampId, bytes32 offRampId)\\n {\\n _validateProof(_proof.public_values, _proof.proof);\\n\\n _validateTLSEndpoint(endpoint.replaceString(\\\"*\\\", _proof.public_values.profileId), _proof.public_values.endpoint);\\n _validateTLSHost(host, _proof.public_values.host);\\n\\n onRampId = bytes32(_proof.public_values.profileId.stringToUint(0));\\n offRampId = bytes32(_proof.public_values.mcAccountId.stringToUint(0));\\n }\\n\\n /* ============ External Admin Functions ============ */\\n\\n function setVerifierSigningKey(address _verifierSigningKey) external onlyOwner {\\n verifierSigningKey = _verifierSigningKey;\\n\\n emit VerifierSigningKeySet(_verifierSigningKey);\\n }\\n\\n /* ============ View Functions ============ */\\n\\n function verifyProof(\\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationData memory _publicValues, \\n bytes memory _proof\\n )\\n internal\\n view\\n returns(bool)\\n { \\n bytes memory encodedMessage = abi.encode(_publicValues.endpoint, _publicValues.host, _publicValues.profileId, _publicValues.mcAccountId);\\n return _isValidVerifierSignature(encodedMessage, _proof, verifierSigningKey);\\n }\\n\\n /* ============ Internal Functions ============ */\\n\\n function _validateProof(\\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationData memory _publicValues, \\n bytes memory _proof\\n )\\n internal\\n view\\n { \\n require(\\n verifyProof(_publicValues, _proof),\\n \\\"Invalid signature from verifier\\\"\\n );\\n }\\n}\\n\",\"keccak256\":\"0xfac01e1549a6462126922f8bb5526fea57dcaed12c3e3ad22fa109f9ca0c016a\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseOffRamperRegistrationProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseOffRamperRegistrationProcessor {\\n\\n struct OffRamperRegistrationData {\\n string endpoint;\\n string host;\\n string profileId;\\n string mcAccountId;\\n }\\n\\n struct OffRamperRegistrationProof {\\n OffRamperRegistrationData public_values;\\n bytes proof;\\n }\\n\\n function processProof(\\n OffRamperRegistrationProof calldata _proof\\n )\\n external\\n returns (bytes32, bytes32);\\n}\\n\",\"keccak256\":\"0x1ca016325effca3a3d66ffa59d5a6bb694f4daca8ba9d57542f1beea73f2ceec\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162001a1938038062001a198339810160408190526200003491620001e2565b85848484846200004433620000b4565b6001600160a01b03851660805260016200005f838262000324565b5060026200006e828262000324565b5050600380546001600160a01b039485166001600160a01b03199182161790915560049290925550600580549890921697169690961790955550620003f0945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200011a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200014557600080fd5b81516001600160401b03808211156200016257620001626200011d565b604051601f8301601f19908116603f011681019082821181831017156200018d576200018d6200011d565b81604052838152602092508683858801011115620001aa57600080fd5b600091505b83821015620001ce5785820183015181830184015290820190620001af565b600093810190920192909252949350505050565b60008060008060008060c08789031215620001fc57600080fd5b8651620002098162000104565b60208801519096506200021c8162000104565b60408801519095506200022f8162000104565b6060880151608089015191955093506001600160401b03808211156200025457600080fd5b620002628a838b0162000133565b935060a08901519150808211156200027957600080fd5b506200028889828a0162000133565b9150509295509295509295565b600181811c90821680620002aa57607f821691505b602082108103620002cb57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200031f57600081815260208120601f850160051c81016020861015620002fa5750805b601f850160051c820191505b818110156200031b5782815560010162000306565b5050505b505050565b81516001600160401b038111156200034057620003406200011d565b620003588162000351845462000295565b84620002d1565b602080601f831160018114620003905760008415620003775750858301515b600019600386901b1c1916600185901b1785556200031b565b600085815260208120601f198616915b82811015620003c157888601518255948401946001909101908401620003a0565b5085821015620003e05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051611607620004126000396000818160ee015261023d01526116076000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80638da5cb5b116100715780638da5cb5b1461016a578063b2a3fda41461017b578063b870676c1461018e578063dbac5821146101a1578063f2fde38b146101b8578063f437bc59146101cb57600080fd5b80630fa4ed4d146100b957806315d276e1146100e95780634e06a32b146101105780634f80c920146101255780635e280f111461014d578063715018a614610162575b600080fd5b6005546100cc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100cc7f000000000000000000000000000000000000000000000000000000000000000081565b61012361011e366004611066565b6101d3565b005b61013861013336600461108f565b61022f565b604080519283526020830191909152016100e0565b6101556105c7565b6040516100e0919061111a565b610123610655565b6000546001600160a01b03166100cc565b61012361018936600461112d565b610669565b6003546100cc906001600160a01b031681565b6101aa60045481565b6040519081526020016100e0565b6101236101c6366004611066565b610676565b6101556106ef565b6101db6106fc565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fb8603ceabf8ee4633f1fd8c0ae9e0e64f2fc2fea5cb79a96c18efd007aab6f969060200160405180910390a150565b600080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102af5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792052616d702063616e2063616c6c20746869732066756e6374696f6e60448201526064015b60405180910390fd5b61030c6102bc8480611146565b6102c590611232565b6102d260208601866112e9565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061075692505050565b6040805180820190915260018152601560f91b602082015261046290610414906103368680611146565b6103449060408101906112e9565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050600180549092506103879150611330565b80601f01602080910402602001604051908101604052809291908181526020018280546103b390611330565b80156104005780601f106103d557610100808354040283529160200191610400565b820191906000526020600020905b8154815290600101906020018083116103e357829003601f168201915b50505050506107b09092919063ffffffff16565b61041e8580611146565b61042890806112e9565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083592505050565b6105466002805461047290611330565b80601f016020809104026020016040519081016040528092919081815260200182805461049e90611330565b80156104eb5780601f106104c0576101008083540402835291602001916104eb565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b506104fe93508892508291506111469050565b61050c9060208101906112e9565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506108d092505050565b6105a060006105558580611146565b6105639060408101906112e9565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929392505061096b9050565b91506105bf60006105b18580611146565b6105639060608101906112e9565b919391925050565b600180546105d490611330565b80601f016020809104026020016040519081016040528092919081815260200182805461060090611330565b801561064d5780601f106106225761010080835404028352916020019161064d565b820191906000526020600020905b81548152906001019060200180831161063057829003601f168201915b505050505081565b61065d6106fc565b6106676000610985565b565b6106716106fc565b600455565b61067e6106fc565b6001600160a01b0381166106e35760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102a6565b6106ec81610985565b50565b600280546105d490611330565b6000546001600160a01b031633146106675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102a6565b61076082826109d5565b6107ac5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e61747572652066726f6d2076657269666965720060448201526064016102a6565b5050565b6060838360006107c08383610a33565b905060001981036107d65786935050505061082e565b60006107e488600084610b12565b90506000610800898551856107f99190611380565b8751610b12565b905081878260405160200161081793929190611393565b604051602081830303815290604052955050505050505b9392505050565b80604051602001610846919061111a565b604051602081830303815290604052805190602001208260405160200161086d919061111a565b60405160208183030381529060405280519060200120146107ac5760405162461bcd60e51b815260206004820181905260248201527f456e64706f696e7420646f6573206e6f74206d6174636820657870656374656460448201526064016102a6565b806040516020016108e1919061111a565b6040516020818303038152906040528051906020012082604051602001610908919061111a565b60405160208183030381529060405280519060200120146107ac5760405162461bcd60e51b815260206004820152601c60248201527f486f737420646f6573206e6f74206d617463682065787065637465640000000060448201526064016102a6565b600061097c83601760f91b84610bdf565b90505b92915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008083600001518460200151856040015186606001516040516020016109ff94939291906113d6565b60408051601f19818403018152919052600554909150610a2b90829085906001600160a01b0316610dbc565b949350505050565b80518251600091849184911115610a50576000199250505061097f565b60005b81518351610a61919061142e565b8111610b0557600160005b8351811015610ae057838181518110610a8757610a87611441565b01602001516001600160f81b03191685610aa18386611380565b81518110610ab157610ab1611441565b01602001516001600160f81b03191614610ace5760009150610ae0565b80610ad881611457565b915050610a6c565b508015610af25750925061097f915050565b5080610afd81611457565b915050610a53565b5060001995945050505050565b6060836000610b21858561142e565b67ffffffffffffffff811115610b3957610b39611166565b6040519080825280601f01601f191660200182016040528015610b63576020820181803683370190505b509050845b84811015610bd557828181518110610b8257610b82611441565b01602001516001600160f81b03191682610b9c888461142e565b81518110610bac57610bac611441565b60200101906001600160f81b031916908160001a90535080610bcd81611457565b915050610b68565b5095945050505050565b600083818080805b8451811015610d3557603060f81b858281518110610c0757610c07611441565b01602001516001600160f81b03191610801590610c485750603960f81b858281518110610c3657610c36611441565b01602001516001600160f81b03191611155b15610c8b576030858281518110610c6157610c61611441565b0160200151610c73919060f81c61142e565b610c7e85600a611470565b610c889190611380565b93505b8115610c9f5782610c9b81611457565b9350505b876001600160f81b031916858281518110610cbc57610cbc611441565b01602001516001600160f81b03191603610d23578115610d1e5760405162461bcd60e51b815260206004820152601c60248201527f537472696e6720686173206d756c7469706c6520646563696d616c730000000060448201526064016102a6565b600191505b80610d2d81611457565b915050610be7565b5085821115610d915760405162461bcd60e51b815260206004820152602260248201527f537472696e672068617320746f6f206d616e7920646563696d616c20706c6163604482015261657360f01b60648201526084016102a6565b610d9b828761142e565b610da690600a61156b565b610db09084611470565b98975050505050505050565b825160208401207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c8120610e076001600160a01b0384168286610e10565b95945050505050565b6000806000610e1f8585610e71565b90925090506000816004811115610e3857610e38611577565b148015610e565750856001600160a01b0316826001600160a01b0316145b80610e675750610e67868686610eb6565b9695505050505050565b6000808251604103610ea75760208301516040840151606085015160001a610e9b87828585610fa2565b94509450505050610eaf565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b8686604051602401610ee092919061158d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610f1e91906115a6565b600060405180830381855afa9150503d8060008114610f59576040519150601f19603f3d011682016040523d82523d6000602084013e610f5e565b606091505b5091509150818015610f7257506020815110155b8015610e6757508051630b135d3f60e11b90610f9790830160209081019084016115b8565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610fd9575060009050600361105d565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561102d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166110565760006001925092505061105d565b9150600090505b94509492505050565b60006020828403121561107857600080fd5b81356001600160a01b038116811461082e57600080fd5b6000602082840312156110a157600080fd5b813567ffffffffffffffff8111156110b857600080fd5b82016040818503121561082e57600080fd5b60005b838110156110e55781810151838201526020016110cd565b50506000910152565b600081518084526111068160208601602086016110ca565b601f01601f19169290920160200192915050565b60208152600061097c60208301846110ee565b60006020828403121561113f57600080fd5b5035919050565b60008235607e1983360301811261115c57600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561119f5761119f611166565b60405290565b600082601f8301126111b657600080fd5b813567ffffffffffffffff808211156111d1576111d1611166565b604051601f8301601f19908116603f011681019082821181831017156111f9576111f9611166565b8160405283815286602085880101111561121257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006080823603121561124457600080fd5b61124c61117c565b823567ffffffffffffffff8082111561126457600080fd5b611270368387016111a5565b8352602085013591508082111561128657600080fd5b611292368387016111a5565b602084015260408501359150808211156112ab57600080fd5b6112b7368387016111a5565b604084015260608501359150808211156112d057600080fd5b506112dd368286016111a5565b60608301525092915050565b6000808335601e1984360301811261130057600080fd5b83018035915067ffffffffffffffff82111561131b57600080fd5b602001915036819003821315610eaf57600080fd5b600181811c9082168061134457607f821691505b60208210810361136457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561097f5761097f61136a565b600084516113a58184602089016110ca565b8451908301906113b98183602089016110ca565b84519101906113cc8183602088016110ca565b0195945050505050565b6080815260006113e960808301876110ee565b82810360208401526113fb81876110ee565b9050828103604084015261140f81866110ee565b9050828103606084015261142381856110ee565b979650505050505050565b8181038181111561097f5761097f61136a565b634e487b7160e01b600052603260045260246000fd5b6000600182016114695761146961136a565b5060010190565b808202811582820484141761097f5761097f61136a565b600181815b808511156114c25781600019048211156114a8576114a861136a565b808516156114b557918102915b93841c939080029061148c565b509250929050565b6000826114d95750600161097f565b816114e65750600061097f565b81600181146114fc576002811461150657611522565b600191505061097f565b60ff8411156115175761151761136a565b50506001821b61097f565b5060208310610133831016604e8410600b8410161715611545575081810a61097f565b61154f8383611487565b80600019048211156115635761156361136a565b029392505050565b600061097c83836114ca565b634e487b7160e01b600052602160045260246000fd5b828152604060208201526000610a2b60408301846110ee565b6000825161115c8184602087016110ca565b6000602082840312156115ca57600080fd5b505191905056fea26469706673582212202570aab70dc8bfb1a90d6b61cbe29baa07bdccb3e4115f3a4e9baff27fb7069164736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80638da5cb5b116100715780638da5cb5b1461016a578063b2a3fda41461017b578063b870676c1461018e578063dbac5821146101a1578063f2fde38b146101b8578063f437bc59146101cb57600080fd5b80630fa4ed4d146100b957806315d276e1146100e95780634e06a32b146101105780634f80c920146101255780635e280f111461014d578063715018a614610162575b600080fd5b6005546100cc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100cc7f000000000000000000000000000000000000000000000000000000000000000081565b61012361011e366004611066565b6101d3565b005b61013861013336600461108f565b61022f565b604080519283526020830191909152016100e0565b6101556105c7565b6040516100e0919061111a565b610123610655565b6000546001600160a01b03166100cc565b61012361018936600461112d565b610669565b6003546100cc906001600160a01b031681565b6101aa60045481565b6040519081526020016100e0565b6101236101c6366004611066565b610676565b6101556106ef565b6101db6106fc565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527fb8603ceabf8ee4633f1fd8c0ae9e0e64f2fc2fea5cb79a96c18efd007aab6f969060200160405180910390a150565b600080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102af5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792052616d702063616e2063616c6c20746869732066756e6374696f6e60448201526064015b60405180910390fd5b61030c6102bc8480611146565b6102c590611232565b6102d260208601866112e9565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061075692505050565b6040805180820190915260018152601560f91b602082015261046290610414906103368680611146565b6103449060408101906112e9565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050600180549092506103879150611330565b80601f01602080910402602001604051908101604052809291908181526020018280546103b390611330565b80156104005780601f106103d557610100808354040283529160200191610400565b820191906000526020600020905b8154815290600101906020018083116103e357829003601f168201915b50505050506107b09092919063ffffffff16565b61041e8580611146565b61042890806112e9565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083592505050565b6105466002805461047290611330565b80601f016020809104026020016040519081016040528092919081815260200182805461049e90611330565b80156104eb5780601f106104c0576101008083540402835291602001916104eb565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b506104fe93508892508291506111469050565b61050c9060208101906112e9565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506108d092505050565b6105a060006105558580611146565b6105639060408101906112e9565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929392505061096b9050565b91506105bf60006105b18580611146565b6105639060608101906112e9565b919391925050565b600180546105d490611330565b80601f016020809104026020016040519081016040528092919081815260200182805461060090611330565b801561064d5780601f106106225761010080835404028352916020019161064d565b820191906000526020600020905b81548152906001019060200180831161063057829003601f168201915b505050505081565b61065d6106fc565b6106676000610985565b565b6106716106fc565b600455565b61067e6106fc565b6001600160a01b0381166106e35760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102a6565b6106ec81610985565b50565b600280546105d490611330565b6000546001600160a01b031633146106675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102a6565b61076082826109d5565b6107ac5760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e61747572652066726f6d2076657269666965720060448201526064016102a6565b5050565b6060838360006107c08383610a33565b905060001981036107d65786935050505061082e565b60006107e488600084610b12565b90506000610800898551856107f99190611380565b8751610b12565b905081878260405160200161081793929190611393565b604051602081830303815290604052955050505050505b9392505050565b80604051602001610846919061111a565b604051602081830303815290604052805190602001208260405160200161086d919061111a565b60405160208183030381529060405280519060200120146107ac5760405162461bcd60e51b815260206004820181905260248201527f456e64706f696e7420646f6573206e6f74206d6174636820657870656374656460448201526064016102a6565b806040516020016108e1919061111a565b6040516020818303038152906040528051906020012082604051602001610908919061111a565b60405160208183030381529060405280519060200120146107ac5760405162461bcd60e51b815260206004820152601c60248201527f486f737420646f6573206e6f74206d617463682065787065637465640000000060448201526064016102a6565b600061097c83601760f91b84610bdf565b90505b92915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008083600001518460200151856040015186606001516040516020016109ff94939291906113d6565b60408051601f19818403018152919052600554909150610a2b90829085906001600160a01b0316610dbc565b949350505050565b80518251600091849184911115610a50576000199250505061097f565b60005b81518351610a61919061142e565b8111610b0557600160005b8351811015610ae057838181518110610a8757610a87611441565b01602001516001600160f81b03191685610aa18386611380565b81518110610ab157610ab1611441565b01602001516001600160f81b03191614610ace5760009150610ae0565b80610ad881611457565b915050610a6c565b508015610af25750925061097f915050565b5080610afd81611457565b915050610a53565b5060001995945050505050565b6060836000610b21858561142e565b67ffffffffffffffff811115610b3957610b39611166565b6040519080825280601f01601f191660200182016040528015610b63576020820181803683370190505b509050845b84811015610bd557828181518110610b8257610b82611441565b01602001516001600160f81b03191682610b9c888461142e565b81518110610bac57610bac611441565b60200101906001600160f81b031916908160001a90535080610bcd81611457565b915050610b68565b5095945050505050565b600083818080805b8451811015610d3557603060f81b858281518110610c0757610c07611441565b01602001516001600160f81b03191610801590610c485750603960f81b858281518110610c3657610c36611441565b01602001516001600160f81b03191611155b15610c8b576030858281518110610c6157610c61611441565b0160200151610c73919060f81c61142e565b610c7e85600a611470565b610c889190611380565b93505b8115610c9f5782610c9b81611457565b9350505b876001600160f81b031916858281518110610cbc57610cbc611441565b01602001516001600160f81b03191603610d23578115610d1e5760405162461bcd60e51b815260206004820152601c60248201527f537472696e6720686173206d756c7469706c6520646563696d616c730000000060448201526064016102a6565b600191505b80610d2d81611457565b915050610be7565b5085821115610d915760405162461bcd60e51b815260206004820152602260248201527f537472696e672068617320746f6f206d616e7920646563696d616c20706c6163604482015261657360f01b60648201526084016102a6565b610d9b828761142e565b610da690600a61156b565b610db09084611470565b98975050505050505050565b825160208401207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c8120610e076001600160a01b0384168286610e10565b95945050505050565b6000806000610e1f8585610e71565b90925090506000816004811115610e3857610e38611577565b148015610e565750856001600160a01b0316826001600160a01b0316145b80610e675750610e67868686610eb6565b9695505050505050565b6000808251604103610ea75760208301516040840151606085015160001a610e9b87828585610fa2565b94509450505050610eaf565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b8686604051602401610ee092919061158d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610f1e91906115a6565b600060405180830381855afa9150503d8060008114610f59576040519150601f19603f3d011682016040523d82523d6000602084013e610f5e565b606091505b5091509150818015610f7257506020815110155b8015610e6757508051630b135d3f60e11b90610f9790830160209081019084016115b8565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610fd9575060009050600361105d565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561102d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166110565760006001925092505061105d565b9150600090505b94509492505050565b60006020828403121561107857600080fd5b81356001600160a01b038116811461082e57600080fd5b6000602082840312156110a157600080fd5b813567ffffffffffffffff8111156110b857600080fd5b82016040818503121561082e57600080fd5b60005b838110156110e55781810151838201526020016110cd565b50506000910152565b600081518084526111068160208601602086016110ca565b601f01601f19169290920160200192915050565b60208152600061097c60208301846110ee565b60006020828403121561113f57600080fd5b5035919050565b60008235607e1983360301811261115c57600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561119f5761119f611166565b60405290565b600082601f8301126111b657600080fd5b813567ffffffffffffffff808211156111d1576111d1611166565b604051601f8301601f19908116603f011681019082821181831017156111f9576111f9611166565b8160405283815286602085880101111561121257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006080823603121561124457600080fd5b61124c61117c565b823567ffffffffffffffff8082111561126457600080fd5b611270368387016111a5565b8352602085013591508082111561128657600080fd5b611292368387016111a5565b602084015260408501359150808211156112ab57600080fd5b6112b7368387016111a5565b604084015260608501359150808211156112d057600080fd5b506112dd368286016111a5565b60608301525092915050565b6000808335601e1984360301811261130057600080fd5b83018035915067ffffffffffffffff82111561131b57600080fd5b602001915036819003821315610eaf57600080fd5b600181811c9082168061134457607f821691505b60208210810361136457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561097f5761097f61136a565b600084516113a58184602089016110ca565b8451908301906113b98183602089016110ca565b84519101906113cc8183602088016110ca565b0195945050505050565b6080815260006113e960808301876110ee565b82810360208401526113fb81876110ee565b9050828103604084015261140f81866110ee565b9050828103606084015261142381856110ee565b979650505050505050565b8181038181111561097f5761097f61136a565b634e487b7160e01b600052603260045260246000fd5b6000600182016114695761146961136a565b5060010190565b808202811582820484141761097f5761097f61136a565b600181815b808511156114c25781600019048211156114a8576114a861136a565b808516156114b557918102915b93841c939080029061148c565b509250929050565b6000826114d95750600161097f565b816114e65750600061097f565b81600181146114fc576002811461150657611522565b600191505061097f565b60ff8411156115175761151761136a565b50506001821b61097f565b5060208310610133831016604e8410600b8410161715611545575081810a61097f565b61154f8383611487565b80600019048211156115635761156361136a565b029392505050565b600061097c83836114ca565b634e487b7160e01b600052602160045260246000fd5b828152604060208201526000610a2b60408301846110ee565b6000825161115c8184602087016110ca565b6000602082840312156115ca57600080fd5b505191905056fea26469706673582212202570aab70dc8bfb1a90d6b61cbe29baa07bdccb3e4115f3a4e9baff27fb7069164736f6c63430008120033", "devdoc": { "kind": "dev", "methods": { @@ -349,7 +349,7 @@ "type": "t_address" }, { - "astId": 5432, + "astId": 2831, "contract": "contracts/ramps/wise/WiseOffRamperRegistrationProcessor.sol:WiseOffRamperRegistrationProcessor", "label": "endpoint", "offset": 0, @@ -357,7 +357,7 @@ "type": "t_string_storage" }, { - "astId": 5434, + "astId": 2833, "contract": "contracts/ramps/wise/WiseOffRamperRegistrationProcessor.sol:WiseOffRamperRegistrationProcessor", "label": "host", "offset": 0, @@ -365,15 +365,15 @@ "type": "t_string_storage" }, { - "astId": 5437, + "astId": 2836, "contract": "contracts/ramps/wise/WiseOffRamperRegistrationProcessor.sol:WiseOffRamperRegistrationProcessor", "label": "nullifierRegistry", "offset": 0, "slot": "3", - "type": "t_contract(INullifierRegistry)5831" + "type": "t_contract(INullifierRegistry)3027" }, { - "astId": 5439, + "astId": 2838, "contract": "contracts/ramps/wise/WiseOffRamperRegistrationProcessor.sol:WiseOffRamperRegistrationProcessor", "label": "timestampBuffer", "offset": 0, @@ -381,7 +381,7 @@ "type": "t_uint256" }, { - "astId": 18767, + "astId": 4052, "contract": "contracts/ramps/wise/WiseOffRamperRegistrationProcessor.sol:WiseOffRamperRegistrationProcessor", "label": "verifierSigningKey", "offset": 0, @@ -395,7 +395,7 @@ "label": "address", "numberOfBytes": "20" }, - "t_contract(INullifierRegistry)5831": { + "t_contract(INullifierRegistry)3027": { "encoding": "inplace", "label": "contract INullifierRegistry", "numberOfBytes": "20" diff --git a/contracts/deployments/sepolia/WiseRamp.json b/contracts/deployments/sepolia/WiseRamp.json index 89454cd85..0c2b7492a 100644 --- a/contracts/deployments/sepolia/WiseRamp.json +++ b/contracts/deployments/sepolia/WiseRamp.json @@ -1,5 +1,5 @@ { - "address": "0xfb5294d3E7EDE246dcD933b064ADcBd2e2624059", + "address": "0x96805415F53A166d6CC16B3CAA9EE085E28511b9", "abi": [ { "inputs": [ @@ -1249,48 +1249,48 @@ "type": "function" } ], - "transactionHash": "0x7fddd5829aa42731ab61985d996d79b19d9066919ed044eca387aad88985802c", + "transactionHash": "0x76d58579da60b092a8bac1b1767b70c3e7473ed43ad4151b067d7e9dc3855079", "receipt": { "to": null, "from": "0x4e39cF8578698131c57404e8bc3eEC820EDa51d8", - "contractAddress": "0xfb5294d3E7EDE246dcD933b064ADcBd2e2624059", - "transactionIndex": 33, - "gasUsed": "4131968", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000800020000000000000000000800000000000000000000000000000000400000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000010000020000000000100000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x675b6f0c96d223871493d31dde9bc86f34d56fbe920805efbec4b4072f92d0c8", - "transactionHash": "0x7fddd5829aa42731ab61985d996d79b19d9066919ed044eca387aad88985802c", + "contractAddress": "0x96805415F53A166d6CC16B3CAA9EE085E28511b9", + "transactionIndex": 66, + "gasUsed": "4087757", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000010000800000000000000020000000000100000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x9bef9b73acf5273f72c8b7bcc03c407e07eab404f6fcccf0b3ce25cf52f0c576", + "transactionHash": "0x76d58579da60b092a8bac1b1767b70c3e7473ed43ad4151b067d7e9dc3855079", "logs": [ { - "transactionIndex": 33, - "blockNumber": 5573232, - "transactionHash": "0x7fddd5829aa42731ab61985d996d79b19d9066919ed044eca387aad88985802c", - "address": "0xfb5294d3E7EDE246dcD933b064ADcBd2e2624059", + "transactionIndex": 66, + "blockNumber": 5635192, + "transactionHash": "0x76d58579da60b092a8bac1b1767b70c3e7473ed43ad4151b067d7e9dc3855079", + "address": "0x96805415F53A166d6CC16B3CAA9EE085E28511b9", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000004e39cf8578698131c57404e8bc3eec820eda51d8" ], "data": "0x", - "logIndex": 30, - "blockHash": "0x675b6f0c96d223871493d31dde9bc86f34d56fbe920805efbec4b4072f92d0c8" + "logIndex": 110, + "blockHash": "0x9bef9b73acf5273f72c8b7bcc03c407e07eab404f6fcccf0b3ce25cf52f0c576" }, { - "transactionIndex": 33, - "blockNumber": 5573232, - "transactionHash": "0x7fddd5829aa42731ab61985d996d79b19d9066919ed044eca387aad88985802c", - "address": "0xfb5294d3E7EDE246dcD933b064ADcBd2e2624059", + "transactionIndex": 66, + "blockNumber": 5635192, + "transactionHash": "0x76d58579da60b092a8bac1b1767b70c3e7473ed43ad4151b067d7e9dc3855079", + "address": "0x96805415F53A166d6CC16B3CAA9EE085E28511b9", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000004e39cf8578698131c57404e8bc3eec820eda51d8", "0x0000000000000000000000004e39cf8578698131c57404e8bc3eec820eda51d8" ], "data": "0x", - "logIndex": 31, - "blockHash": "0x675b6f0c96d223871493d31dde9bc86f34d56fbe920805efbec4b4072f92d0c8" + "logIndex": 111, + "blockHash": "0x9bef9b73acf5273f72c8b7bcc03c407e07eab404f6fcccf0b3ce25cf52f0c576" } ], - "blockNumber": 5573232, - "cumulativeGasUsed": "6787971", + "blockNumber": 5635192, + "cumulativeGasUsed": "14321379", "status": 1, "byzantium": true }, @@ -1305,10 +1305,10 @@ "0x4e39cF8578698131c57404e8bc3eEC820EDa51d8" ], "numDeployments": 1, - "solcInputHash": "6e4c0155cf194d54974389502ced73c2", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"contract IERC20\",\"name\":\"_usdc\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minDepositAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxOnRampAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_intentExpirationPeriod\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_onRampCooldownPeriod\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_sustainabilityFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sustainabilityFeeRecipient\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"}],\"name\":\"DepositClosed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"offRampId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"currencyId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"conversionRate\",\"type\":\"uint256\"}],\"name\":\"DepositReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DepositWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"intentExpirationPeriod\",\"type\":\"uint256\"}],\"name\":\"IntentExpirationPeriodSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"intentHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"onRamper\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"}],\"name\":\"IntentFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"intentHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"}],\"name\":\"IntentPruned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"intentHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"accountId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"IntentSignaled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxOnRampAmount\",\"type\":\"uint256\"}],\"name\":\"MaxOnRampAmountSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"minDepositAmount\",\"type\":\"uint256\"}],\"name\":\"MinDepositAmountSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sendProcessor\",\"type\":\"address\"}],\"name\":\"NewSendProcessorSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"onRampCooldownPeriod\",\"type\":\"uint256\"}],\"name\":\"OnRampCooldownPeriodSet\",\"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\":false,\"internalType\":\"address\",\"name\":\"feeRecipient\",\"type\":\"address\"}],\"name\":\"SustainabilityFeeRecipientUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"name\":\"SustainabilityFeeUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountRegistry\",\"outputs\":[{\"internalType\":\"contract IWiseAccountRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_intentHash\",\"type\":\"bytes32\"}],\"name\":\"cancelIntent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositCounter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"wiseTag\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"verifierSigningKey\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"depositAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"receiveCurrencyId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"remainingDeposits\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outstandingIntentAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"conversionRate\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getAccountDeposits\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"depositorId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"wiseTag\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"verifierSigningKey\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"depositAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"receiveCurrencyId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"remainingDeposits\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outstandingIntentAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"conversionRate\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"intentHashes\",\"type\":\"bytes32[]\"}],\"internalType\":\"struct WiseRamp.Deposit\",\"name\":\"deposit\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"availableLiquidity\",\"type\":\"uint256\"}],\"internalType\":\"struct WiseRamp.DepositWithAvailableLiquidity[]\",\"name\":\"accountDeposits\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_depositId\",\"type\":\"uint256\"}],\"name\":\"getDeposit\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"wiseTag\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"verifierSigningKey\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"depositAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"receiveCurrencyId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"remainingDeposits\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outstandingIntentAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"conversionRate\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"intentHashes\",\"type\":\"bytes32[]\"}],\"internalType\":\"struct WiseRamp.Deposit\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_depositIds\",\"type\":\"uint256[]\"}],\"name\":\"getDepositFromIds\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"depositorId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"wiseTag\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"verifierSigningKey\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"depositAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"receiveCurrencyId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"remainingDeposits\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outstandingIntentAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"conversionRate\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"intentHashes\",\"type\":\"bytes32[]\"}],\"internalType\":\"struct WiseRamp.Deposit\",\"name\":\"deposit\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"availableLiquidity\",\"type\":\"uint256\"}],\"internalType\":\"struct WiseRamp.DepositWithAvailableLiquidity[]\",\"name\":\"depositArray\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getIdCurrentIntentHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getIdCurrentIntentHashAsUint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"_intentHashes\",\"type\":\"bytes32[]\"}],\"name\":\"getIntentsWithOnRamperId\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"intentHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"onRamper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"intentTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"struct WiseRamp.Intent\",\"name\":\"intent\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"onRamperId\",\"type\":\"bytes32\"}],\"internalType\":\"struct WiseRamp.IntentWithOnRamperId[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getLastOnRampTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWiseAccountRegistry\",\"name\":\"_accountRegistry\",\"type\":\"address\"},{\"internalType\":\"contract IWiseSendProcessor\",\"name\":\"_sendProcessor\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"intentExpirationPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"intents\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRamper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"intentTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxOnRampAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minDepositAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_wiseTag\",\"type\":\"string\"},{\"internalType\":\"bytes32\",\"name\":\"_receiveCurrencyId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_depositAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_receiveAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"}],\"name\":\"offRamp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"transferId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"senderId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"recipientId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"amount\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"currencyId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"status\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"timestamp\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"intentHash\",\"type\":\"uint256\"}],\"internalType\":\"struct IWiseSendProcessor.SendData\",\"name\":\"_sendData\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"_verifierSignature\",\"type\":\"bytes\"}],\"name\":\"onRamp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"onRampCooldownPeriod\",\"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\":\"bytes32\",\"name\":\"_intentHash\",\"type\":\"bytes32\"}],\"name\":\"releaseFundsToOnramper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sendProcessor\",\"outputs\":[{\"internalType\":\"contract IWiseSendProcessor\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_intentExpirationPeriod\",\"type\":\"uint256\"}],\"name\":\"setIntentExpirationPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxOnRampAmount\",\"type\":\"uint256\"}],\"name\":\"setMaxOnRampAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minDepositAmount\",\"type\":\"uint256\"}],\"name\":\"setMinDepositAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_onRampCooldownPeriod\",\"type\":\"uint256\"}],\"name\":\"setOnRampCooldownPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWiseSendProcessor\",\"name\":\"_sendProcessor\",\"type\":\"address\"}],\"name\":\"setSendProcessor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"setSustainabilityFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_feeRecipient\",\"type\":\"address\"}],\"name\":\"setSustainabilityFeeRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_depositId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"signalIntent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sustainabilityFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sustainabilityFeeRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"usdc\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_depositIds\",\"type\":\"uint256[]\"}],\"name\":\"withdrawDeposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelIntent(bytes32)\":{\"params\":{\"_intentHash\":\"Hash of intent being cancelled\"}},\"initialize(address,address)\":{\"params\":{\"_accountRegistry\":\"Account Registry contract for Wise\",\"_sendProcessor\":\"Send processor address\"}},\"offRamp(string,bytes32,uint256,uint256,address)\":{\"params\":{\"_depositAmount\":\"The amount of USDC to off-ramp\",\"_receiveAmount\":\"The amount of USD to receive\",\"_receiveCurrencyId\":\"Id of the currency to be received off-chain\",\"_verifierSigningKey\":\"Public key of the verifier depositor wants to sign the TLS proof\",\"_wiseTag\":\"Depositor's Wise tag to receive payments\"}},\"onRamp((string,string,string,string,string,string,string,string,string,uint256),bytes)\":{\"params\":{\"_sendData\":\"Struct containing unredacted data from API call to Wise\",\"_verifierSignature\":\"Signature by verifier of the unredacted data\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"releaseFundsToOnramper(bytes32)\":{\"params\":{\"_intentHash\":\"Hash of intent to resolve by releasing the funds\"}},\"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.\"},\"setIntentExpirationPeriod(uint256)\":{\"params\":{\"_intentExpirationPeriod\":\"New intent expiration period\"}},\"setMaxOnRampAmount(uint256)\":{\"params\":{\"_maxOnRampAmount\":\"The new max on ramp amount\"}},\"setMinDepositAmount(uint256)\":{\"params\":{\"_minDepositAmount\":\"The new minimum deposit amount\"}},\"setOnRampCooldownPeriod(uint256)\":{\"params\":{\"_onRampCooldownPeriod\":\"New on-ramp cooldown period\"}},\"setSendProcessor(address)\":{\"params\":{\"_sendProcessor\":\"New send proccesor address\"}},\"setSustainabilityFee(uint256)\":{\"params\":{\"_fee\":\"The new sustainability fee in precise units (10**18, ie 10% = 1e17)\"}},\"setSustainabilityFeeRecipient(address)\":{\"params\":{\"_feeRecipient\":\"The new fee recipient address\"}},\"signalIntent(uint256,uint256,address)\":{\"params\":{\"_amount\":\"The amount of USDC the user wants to on-ramp\",\"_depositId\":\"The ID of the deposit the on-ramper intends to use for \",\"_to\":\"Address to forward funds to (can be same as onRamper)\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"withdrawDeposit(uint256[])\":{\"params\":{\"_depositIds\":\"Array of depositIds the depositor is attempting to withdraw\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelIntent(bytes32)\":{\"notice\":\"Only callable by the originator of the intent. Cancels an outstanding intent thus allowing user to signal a new intent. Deposit state is updated to reflect the cancelled intent.\"},\"initialize(address,address)\":{\"notice\":\"Initialize Ramp with the addresses of the Processors\"},\"offRamp(string,bytes32,uint256,uint256,address)\":{\"notice\":\"Generates a deposit entry for off-rampers that can then be fulfilled by an on-ramper. This function will not add to previous deposits. Every deposit has it's own unique identifier. User must approve the contract to transfer the deposit amount of USDC.\"},\"onRamp((string,string,string,string,string,string,string,string,string,uint256),bytes)\":{\"notice\":\"Anyone can submit an on-ramp transaction, even if caller isn't on-ramper. Upon submission the proof is validated, intent is removed, and deposit state is updated. USDC is transferred to the on-ramper.\"},\"releaseFundsToOnramper(bytes32)\":{\"notice\":\"Allows off-ramper to release funds to the on-ramper in case of a failed on-ramp or because of some other arrangement between the two parties. Upon submission we check to make sure the msg.sender is the depositor, the intent is removed, and deposit state is updated. USDC is transferred to the on-ramper.\"},\"setIntentExpirationPeriod(uint256)\":{\"notice\":\"GOVERNANCE ONLY: Updates the intent expiration period, after this period elapses an intent can be pruned to prevent locking up a depositor's funds.\"},\"setMaxOnRampAmount(uint256)\":{\"notice\":\"GOVERNANCE ONLY: Updates the max amount allowed to be on-ramped in each transaction. To on-ramp more than this amount a user must make multiple transactions.\"},\"setMinDepositAmount(uint256)\":{\"notice\":\"GOVERNANCE ONLY: Updates the minimum deposit amount a user can specify for off-ramping.\"},\"setOnRampCooldownPeriod(uint256)\":{\"notice\":\"GOVERNANCE ONLY: Updates the on-ramp cooldown period, once an on-ramp transaction is completed the user must wait this amount of time before they can signalIntent to on-ramp again.\"},\"setSendProcessor(address)\":{\"notice\":\"GOVERNANCE ONLY: Updates the send processor address used for validating and interpreting zk proofs.\"},\"setSustainabilityFee(uint256)\":{\"notice\":\"GOVERNANCE ONLY: Updates the sustainability fee. This fee is charged to on-rampers upon a successful on-ramp.\"},\"setSustainabilityFeeRecipient(address)\":{\"notice\":\"GOVERNANCE ONLY: Updates the recepient of sustainability fees.\"},\"signalIntent(uint256,uint256,address)\":{\"notice\":\"Signals intent to pay the depositor defined in the _depositId the _amount * deposit conversionRate off-chain in order to unlock _amount of funds on-chain. Each user can only have one outstanding intent at a time regardless of address (tracked using accountId). Caller must not be on the depositor's deny list. If there are prunable intents then they will be deleted from the deposit to be able to maintain state hygiene.\"},\"withdrawDeposit(uint256[])\":{\"notice\":\"Caller must be the depositor for each depositId in the array, if not whole function fails. Depositor is returned all remaining deposits and any outstanding intents that are expired. If an intent is not expired then those funds will not be returned. Deposit will be deleted as long as there are no more outstanding intents.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ramps/wise/WiseRamp.sol\":\"WiseRamp\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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/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/external/Bytes32ArrayUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.17;\\n\\n/**\\n * @title Bytes32ArrayUtils\\n * @author ZKP2P\\n *\\n * Fork of Set Protocol's AddressArrayUtils library adapted for usage with bytes32 arrays.\\n */\\nlibrary Bytes32ArrayUtils {\\n\\n uint256 constant internal MAX_INT = 2**256 - 1;\\n\\n /**\\n * Finds the index of the first occurrence of the given element.\\n * @param A The input array to search\\n * @param a The value to find\\n * @return Returns (index and isIn) for the first occurrence starting from index 0\\n */\\n function indexOf(bytes32[] memory A, bytes32 a) internal pure returns (uint256, bool) {\\n uint256 length = A.length;\\n for (uint256 i = 0; i < length; i++) {\\n if (A[i] == a) {\\n return (i, true);\\n }\\n }\\n return (MAX_INT, false);\\n }\\n\\n /**\\n * Returns true if the value is present in the list. Uses indexOf internally.\\n * @param A The input array to search\\n * @param a The value to find\\n * @return Returns isIn for the first occurrence starting from index 0\\n */\\n function contains(bytes32[] memory A, bytes32 a) internal pure returns (bool) {\\n (, bool isIn) = indexOf(A, a);\\n return isIn;\\n }\\n\\n /**\\n * Returns true if there are 2 elements that are the same in an array\\n * @param A The input array to search\\n * @return Returns boolean for the first occurrence of a duplicate\\n */\\n function hasDuplicate(bytes32[] memory A) internal pure returns(bool) {\\n require(A.length > 0, \\\"A is empty\\\");\\n\\n for (uint256 i = 0; i < A.length - 1; i++) {\\n bytes32 current = A[i];\\n for (uint256 j = i + 1; j < A.length; j++) {\\n if (current == A[j]) {\\n return true;\\n }\\n }\\n }\\n return false;\\n }\\n\\n /**\\n * @param A The input array to search\\n * @param a The bytes32 to remove\\n * @return Returns the array with the object removed.\\n */\\n function remove(bytes32[] memory A, bytes32 a)\\n internal\\n pure\\n returns (bytes32[] memory)\\n {\\n (uint256 index, bool isIn) = indexOf(A, a);\\n if (!isIn) {\\n revert(\\\"bytes32 not in array.\\\");\\n } else {\\n (bytes32[] memory _A,) = pop(A, index);\\n return _A;\\n }\\n }\\n\\n /**\\n * @param A The input array to search\\n * @param a The bytes32 to remove\\n */\\n function removeStorage(bytes32[] storage A, bytes32 a)\\n internal\\n {\\n (uint256 index, bool isIn) = indexOf(A, a);\\n if (!isIn) {\\n revert(\\\"bytes32 not in array.\\\");\\n } else {\\n uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here\\n if (index != lastIndex) { A[index] = A[lastIndex]; }\\n A.pop();\\n }\\n }\\n\\n /**\\n * Removes specified index from array\\n * @param A The input array to search\\n * @param index The index to remove\\n * @return Returns the new array and the removed entry\\n */\\n function pop(bytes32[] memory A, uint256 index)\\n internal\\n pure\\n returns (bytes32[] memory, bytes32)\\n {\\n uint256 length = A.length;\\n require(index < A.length, \\\"Index must be < A length\\\");\\n bytes32[] memory newBytes = new bytes32[](length - 1);\\n for (uint256 i = 0; i < index; i++) {\\n newBytes[i] = A[i];\\n }\\n for (uint256 j = index + 1; j < length; j++) {\\n newBytes[j - 1] = A[j];\\n }\\n return (newBytes, A[index]);\\n }\\n}\\n\",\"keccak256\":\"0x14d572deda126ff812eb5ab0eed33120e13cc568fd611a4a6bff652f3e8440a8\",\"license\":\"MIT\"},\"contracts/external/Uint256ArrayUtils.sol\":{\"content\":\"/*\\n Copyright 2020 Set Labs Inc.\\n\\n Licensed under the Apache License, Version 2.0 (the \\\"License\\\");\\n you may not use this file except in compliance with the License.\\n You may obtain a copy of the License at\\n\\n http://www.apache.org/licenses/LICENSE-2.0\\n\\n Unless required by applicable law or agreed to in writing, software\\n distributed under the License is distributed on an \\\"AS IS\\\" BASIS,\\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\\n See the License for the specific language governing permissions and\\n limitations under the License.\\n\\n SPDX-License-Identifier: Apache-2.0\\n*/\\n\\npragma solidity ^0.8.18;\\n\\n/**\\n * @title Uint256ArrayUtils\\n * @author Set Protocol\\n *\\n * Utility functions to handle Uint256 Arrays\\n */\\nlibrary Uint256ArrayUtils {\\n\\n uint256 constant internal MAX_INT = 2**256 - 1;\\n\\n /**\\n * Finds the index of the first occurrence of the given element.\\n * @param A The input array to search\\n * @param a The value to find\\n * @return Returns (index and isIn) for the first occurrence starting from index 0\\n */\\n function indexOf(uint256[] memory A, uint256 a) internal pure returns (uint256, bool) {\\n uint256 length = A.length;\\n for (uint256 i = 0; i < length; i++) {\\n if (A[i] == a) {\\n return (i, true);\\n }\\n }\\n return (MAX_INT, false);\\n }\\n\\n /**\\n * Returns the combination of the two arrays\\n * @param A The first array\\n * @param B The second array\\n * @return Returns A extended by B\\n */\\n function extend(uint256[] memory A, uint256[] memory B) internal pure returns (uint256[] memory) {\\n uint256 aLength = A.length;\\n uint256 bLength = B.length;\\n uint256[] memory newUints = new uint256[](aLength + bLength);\\n for (uint256 i = 0; i < aLength; i++) {\\n newUints[i] = A[i];\\n }\\n for (uint256 j = 0; j < bLength; j++) {\\n newUints[aLength + j] = B[j];\\n }\\n return newUints;\\n }\\n\\n /**\\n * @param A The input array to search\\n * @param a The bytes32 to remove\\n */\\n function removeStorage(uint256[] storage A, uint256 a)\\n internal\\n {\\n (uint256 index, bool isIn) = indexOf(A, a);\\n if (!isIn) {\\n revert(\\\"uint256 not in array.\\\");\\n } else {\\n uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here\\n if (index != lastIndex) { A[index] = A[lastIndex]; }\\n A.pop();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x102021415f8444ff563fc6d0082f39296f47c09ce73fb4cd642e700ac489eefe\",\"license\":\"Apache-2.0\"},\"contracts/ramps/wise/WiseRamp.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { IERC20 } from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport { Bytes32ArrayUtils } from \\\"../../external/Bytes32ArrayUtils.sol\\\";\\nimport { Uint256ArrayUtils } from \\\"../../external/Uint256ArrayUtils.sol\\\";\\n\\nimport { IWiseAccountRegistry } from \\\"./interfaces/IWiseAccountRegistry.sol\\\";\\nimport { IWiseSendProcessor } from \\\"./interfaces/IWiseSendProcessor.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract WiseRamp is Ownable {\\n\\n using Bytes32ArrayUtils for bytes32[];\\n using Uint256ArrayUtils for uint256[];\\n\\n /* ============ Events ============ */\\n event DepositReceived(\\n uint256 indexed depositId,\\n bytes32 indexed offRampId,\\n bytes32 indexed currencyId,\\n uint256 amount,\\n uint256 conversionRate\\n );\\n event IntentSignaled(\\n bytes32 indexed intentHash,\\n uint256 indexed depositId,\\n bytes32 indexed accountId,\\n address to,\\n uint256 amount,\\n uint256 timestamp\\n );\\n\\n event IntentPruned(\\n bytes32 indexed intentHash,\\n uint256 indexed depositId\\n );\\n event IntentFulfilled(\\n bytes32 indexed intentHash,\\n uint256 indexed depositId,\\n address indexed onRamper,\\n address to,\\n uint256 amount,\\n uint256 feeAmount\\n );\\n event DepositWithdrawn(\\n uint256 indexed depositId,\\n address indexed depositor,\\n uint256 amount\\n );\\n\\n event DepositClosed(uint256 depositId, address depositor);\\n event MinDepositAmountSet(uint256 minDepositAmount);\\n event MaxOnRampAmountSet(uint256 maxOnRampAmount);\\n event IntentExpirationPeriodSet(uint256 intentExpirationPeriod);\\n event OnRampCooldownPeriodSet(uint256 onRampCooldownPeriod);\\n event SustainabilityFeeUpdated(uint256 fee);\\n event SustainabilityFeeRecipientUpdated(address feeRecipient);\\n event NewSendProcessorSet(address sendProcessor);\\n\\n /* ============ Structs ============ */\\n\\n struct Deposit {\\n address depositor;\\n string wiseTag;\\n address verifierSigningKey; // Public key of the verifier depositor wants to sign the TLS proof\\n uint256 depositAmount; // Amount of USDC deposited\\n bytes32 receiveCurrencyId; // Id of the currency to be received off-chain (bytes32(Wise currency code))\\n uint256 remainingDeposits; // Amount of remaining deposited liquidity\\n uint256 outstandingIntentAmount; // Amount of outstanding intents (may include expired intents)\\n uint256 conversionRate; // Conversion required by off-ramper between USDC/USD\\n bytes32[] intentHashes; // Array of hashes of all open intents (may include some expired if not pruned)\\n }\\n\\n struct DepositWithAvailableLiquidity {\\n uint256 depositId; // ID of the deposit\\n bytes32 depositorId; // Depositor's offRampId \\n Deposit deposit; // Deposit struct\\n uint256 availableLiquidity; // Amount of liquidity available to signal intents (net of expired intents)\\n }\\n\\n struct Intent {\\n address onRamper; // On-ramper's address\\n address to; // Address to forward funds to (can be same as onRamper)\\n uint256 deposit; // ID of the deposit the intent is signaling on\\n uint256 amount; // Amount of USDC the on-ramper signals intent for on-chain\\n uint256 intentTimestamp; // Timestamp of when the intent was signaled\\n }\\n\\n struct IntentWithOnRamperId {\\n bytes32 intentHash; // Intent hash\\n Intent intent; // Intent struct\\n bytes32 onRamperId; // onRamper's onRamperId\\n }\\n\\n // A Global Account is defined as an account represented by one accountId. This is used to enforce limitations on actions across\\n // all Ethereum addresses that are associated with that accountId. In this case we use it to enforce a cooldown period between on ramps,\\n // restrict each Wise account to one outstanding intent at a time, and to enforce deny lists.\\n struct GlobalAccountInfo {\\n bytes32 currentIntentHash; // Hash of the current open intent (if exists)\\n uint256 lastOnrampTimestamp; // Timestamp of the last on-ramp transaction used to check if cooldown period elapsed\\n uint256[] deposits; // Array of open account deposits\\n }\\n\\n /* ============ Modifiers ============ */\\n modifier onlyRegisteredUser() {\\n require(accountRegistry.isRegisteredUser(msg.sender), \\\"Caller must be registered user\\\");\\n _;\\n }\\n\\n /* ============ Constants ============ */\\n uint256 internal constant PRECISE_UNIT = 1e18;\\n uint256 internal constant MAX_DEPOSITS = 5; // An account can only have max 5 different deposit parameterizations to prevent locking funds\\n uint256 constant CIRCOM_PRIME_FIELD = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\\n uint256 constant MAX_SUSTAINABILITY_FEE = 5e16; // 5% max sustainability fee\\n \\n /* ============ State Variables ============ */\\n IERC20 public immutable usdc; // USDC token contract\\n IWiseAccountRegistry public accountRegistry; // Account Registry contract for Wise\\n IWiseSendProcessor public sendProcessor; // Address of send processor contract\\n\\n bool public isInitialized; // Indicates if contract has been initialized\\n\\n mapping(bytes32 => GlobalAccountInfo) internal globalAccount; // Mapping of onRamp ID to information used to enforce actions across Ethereum accounts\\n mapping(uint256 => Deposit) public deposits; // Mapping of depositIds to deposit structs\\n mapping(bytes32 => Intent) public intents; // Mapping of intentHashes to intent structs\\n\\n uint256 public minDepositAmount; // Minimum amount of USDC that can be deposited\\n uint256 public maxOnRampAmount; // Maximum amount of USDC that can be on-ramped in a single transaction\\n uint256 public onRampCooldownPeriod; // Time period that must elapse between completing an on-ramp and signaling a new intent\\n uint256 public intentExpirationPeriod; // Time period after which an intent can be pruned from the system\\n uint256 public sustainabilityFee; // Fee charged to on-rampers in preciseUnits (1e16 = 1%)\\n address public sustainabilityFeeRecipient; // Address that receives the sustainability fee\\n\\n uint256 public depositCounter; // Counter for depositIds\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _owner,\\n IERC20 _usdc,\\n uint256 _minDepositAmount,\\n uint256 _maxOnRampAmount,\\n uint256 _intentExpirationPeriod,\\n uint256 _onRampCooldownPeriod,\\n uint256 _sustainabilityFee,\\n address _sustainabilityFeeRecipient\\n )\\n Ownable()\\n {\\n usdc = _usdc;\\n minDepositAmount = _minDepositAmount;\\n maxOnRampAmount = _maxOnRampAmount;\\n intentExpirationPeriod = _intentExpirationPeriod;\\n onRampCooldownPeriod = _onRampCooldownPeriod;\\n sustainabilityFee = _sustainabilityFee;\\n sustainabilityFeeRecipient = _sustainabilityFeeRecipient;\\n\\n transferOwnership(_owner);\\n }\\n\\n /* ============ External Functions ============ */\\n\\n /**\\n * @notice Initialize Ramp with the addresses of the Processors\\n *\\n * @param _accountRegistry Account Registry contract for Wise\\n * @param _sendProcessor Send processor address\\n */\\n function initialize(\\n IWiseAccountRegistry _accountRegistry,\\n IWiseSendProcessor _sendProcessor\\n )\\n external\\n onlyOwner\\n {\\n require(!isInitialized, \\\"Already initialized\\\");\\n\\n accountRegistry = _accountRegistry;\\n sendProcessor = _sendProcessor;\\n\\n isInitialized = true;\\n }\\n\\n /**\\n * @notice Generates a deposit entry for off-rampers that can then be fulfilled by an on-ramper. This function will not add to\\n * previous deposits. Every deposit has it's own unique identifier. User must approve the contract to transfer the deposit amount\\n * of USDC.\\n *\\n * @param _wiseTag Depositor's Wise tag to receive payments\\n * @param _receiveCurrencyId Id of the currency to be received off-chain\\n * @param _depositAmount The amount of USDC to off-ramp\\n * @param _receiveAmount The amount of USD to receive\\n * @param _verifierSigningKey Public key of the verifier depositor wants to sign the TLS proof\\n */\\n function offRamp(\\n string calldata _wiseTag,\\n bytes32 _receiveCurrencyId,\\n uint256 _depositAmount,\\n uint256 _receiveAmount,\\n address _verifierSigningKey\\n )\\n external\\n onlyRegisteredUser\\n {\\n IWiseAccountRegistry.AccountInfo memory account = accountRegistry.getAccountInfo(msg.sender);\\n GlobalAccountInfo storage globalAccountInfo = globalAccount[account.accountId];\\n\\n require(account.offRampId != bytes32(0), \\\"Must be registered as off ramper\\\");\\n require(keccak256(abi.encode(_wiseTag)) == account.wiseTagHash, \\\"Wise tag does not match registered wise tag\\\");\\n require(globalAccountInfo.deposits.length < MAX_DEPOSITS, \\\"Maximum deposit amount reached\\\");\\n require(_depositAmount >= minDepositAmount, \\\"Deposit amount must be greater than min deposit amount\\\");\\n require(_receiveAmount > 0, \\\"Receive amount must be greater than 0\\\");\\n\\n uint256 conversionRate = (_depositAmount * PRECISE_UNIT) / _receiveAmount;\\n uint256 depositId = depositCounter++;\\n\\n globalAccountInfo.deposits.push(depositId);\\n\\n deposits[depositId] = Deposit({\\n depositor: msg.sender,\\n wiseTag: _wiseTag,\\n receiveCurrencyId: _receiveCurrencyId,\\n depositAmount: _depositAmount,\\n remainingDeposits: _depositAmount,\\n outstandingIntentAmount: 0,\\n conversionRate: conversionRate,\\n intentHashes: new bytes32[](0),\\n verifierSigningKey: _verifierSigningKey\\n });\\n\\n usdc.transferFrom(msg.sender, address(this), _depositAmount);\\n\\n emit DepositReceived(depositId, account.accountId, _receiveCurrencyId, _depositAmount, conversionRate);\\n }\\n\\n /**\\n * @notice Signals intent to pay the depositor defined in the _depositId the _amount * deposit conversionRate off-chain\\n * in order to unlock _amount of funds on-chain. Each user can only have one outstanding intent at a time regardless of\\n * address (tracked using accountId). Caller must not be on the depositor's deny list. If there are prunable intents then\\n * they will be deleted from the deposit to be able to maintain state hygiene.\\n *\\n * @param _depositId The ID of the deposit the on-ramper intends to use for \\n * @param _amount The amount of USDC the user wants to on-ramp\\n * @param _to Address to forward funds to (can be same as onRamper)\\n */\\n function signalIntent(uint256 _depositId, uint256 _amount, address _to) external onlyRegisteredUser {\\n bytes32 onRamperId = accountRegistry.getAccountId(msg.sender);\\n Deposit storage deposit = deposits[_depositId];\\n\\n // Caller validity checks\\n require(accountRegistry.isAllowedUser(deposit.depositor, onRamperId), \\\"Onramper on depositor's denylist\\\");\\n require(\\n globalAccount[onRamperId].lastOnrampTimestamp + onRampCooldownPeriod <= block.timestamp,\\n \\\"On ramp cool down period not elapsed\\\"\\n );\\n require(globalAccount[onRamperId].currentIntentHash == bytes32(0), \\\"Intent still outstanding\\\");\\n require(accountRegistry.getAccountId(deposit.depositor) != onRamperId, \\\"Sender cannot be the depositor\\\");\\n\\n // Intent information checks\\n require(deposit.depositor != address(0), \\\"Deposit does not exist\\\");\\n require(_amount > 0, \\\"Signaled amount must be greater than 0\\\");\\n require(_amount <= maxOnRampAmount, \\\"Signaled amount must be less than max on-ramp amount\\\");\\n require(_to != address(0), \\\"Cannot send to zero address\\\");\\n\\n bytes32 intentHash = _calculateIntentHash(onRamperId, _depositId);\\n\\n if (deposit.remainingDeposits < _amount) {\\n (\\n bytes32[] memory prunableIntents,\\n uint256 reclaimableAmount\\n ) = _getPrunableIntents(_depositId);\\n\\n require(deposit.remainingDeposits + reclaimableAmount >= _amount, \\\"Not enough liquidity\\\");\\n\\n _pruneIntents(deposit, prunableIntents);\\n deposit.remainingDeposits += reclaimableAmount;\\n deposit.outstandingIntentAmount -= reclaimableAmount;\\n }\\n\\n intents[intentHash] = Intent({\\n onRamper: msg.sender,\\n to: _to,\\n deposit: _depositId,\\n amount: _amount,\\n intentTimestamp: block.timestamp\\n });\\n\\n globalAccount[onRamperId].currentIntentHash = intentHash;\\n\\n deposit.remainingDeposits -= _amount;\\n deposit.outstandingIntentAmount += _amount;\\n deposit.intentHashes.push(intentHash);\\n\\n emit IntentSignaled(intentHash, _depositId, onRamperId, _to, _amount, block.timestamp);\\n }\\n\\n /**\\n * @notice Only callable by the originator of the intent. Cancels an outstanding intent thus allowing user to signal a new\\n * intent. Deposit state is updated to reflect the cancelled intent.\\n *\\n * @param _intentHash Hash of intent being cancelled\\n */\\n function cancelIntent(bytes32 _intentHash) external {\\n Intent memory intent = intents[_intentHash];\\n \\n require(intent.intentTimestamp != 0, \\\"Intent does not exist\\\");\\n require(\\n accountRegistry.getAccountId(intent.onRamper) == accountRegistry.getAccountId(msg.sender),\\n \\\"Sender must be the on-ramper\\\"\\n );\\n\\n Deposit storage deposit = deposits[intent.deposit];\\n\\n _pruneIntent(deposit, _intentHash);\\n\\n deposit.remainingDeposits += intent.amount;\\n deposit.outstandingIntentAmount -= intent.amount;\\n }\\n\\n /**\\n * @notice Anyone can submit an on-ramp transaction, even if caller isn't on-ramper. Upon submission the proof is validated,\\n * intent is removed, and deposit state is updated. USDC is transferred to the on-ramper.\\n *\\n * @param _sendData Struct containing unredacted data from API call to Wise\\n * @param _verifierSignature Signature by verifier of the unredacted data\\n */\\n function onRamp(\\n IWiseSendProcessor.SendData calldata _sendData,\\n bytes calldata _verifierSignature\\n )\\n external\\n {\\n (\\n Intent memory intent,\\n Deposit storage deposit,\\n bytes32 intentHash\\n ) = _verifyOnRampProof(_sendData, _verifierSignature);\\n\\n _pruneIntent(deposit, intentHash);\\n\\n deposit.outstandingIntentAmount -= intent.amount;\\n globalAccount[accountRegistry.getAccountId(intent.onRamper)].lastOnrampTimestamp = block.timestamp;\\n _closeDepositIfNecessary(intent.deposit, deposit);\\n\\n _transferFunds(intentHash, intent);\\n }\\n\\n /**\\n * @notice Allows off-ramper to release funds to the on-ramper in case of a failed on-ramp or because of some other arrangement\\n * between the two parties. Upon submission we check to make sure the msg.sender is the depositor, the intent is removed, and \\n * deposit state is updated. USDC is transferred to the on-ramper.\\n *\\n * @param _intentHash Hash of intent to resolve by releasing the funds\\n */\\n function releaseFundsToOnramper(bytes32 _intentHash) external {\\n Intent memory intent = intents[_intentHash];\\n Deposit storage deposit = deposits[intent.deposit];\\n\\n require(intent.onRamper != address(0), \\\"Intent does not exist\\\");\\n require(deposit.depositor == msg.sender, \\\"Caller must be the depositor\\\");\\n\\n _pruneIntent(deposit, _intentHash);\\n\\n deposit.outstandingIntentAmount -= intent.amount;\\n globalAccount[accountRegistry.getAccountId(intent.onRamper)].lastOnrampTimestamp = block.timestamp;\\n _closeDepositIfNecessary(intent.deposit, deposit);\\n\\n _transferFunds(_intentHash, intent);\\n }\\n\\n /**\\n * @notice Caller must be the depositor for each depositId in the array, if not whole function fails. Depositor is returned all\\n * remaining deposits and any outstanding intents that are expired. If an intent is not expired then those funds will not be\\n * returned. Deposit will be deleted as long as there are no more outstanding intents.\\n *\\n * @param _depositIds Array of depositIds the depositor is attempting to withdraw\\n */\\n function withdrawDeposit(uint256[] memory _depositIds) external {\\n uint256 returnAmount;\\n\\n for (uint256 i = 0; i < _depositIds.length; ++i) {\\n uint256 depositId = _depositIds[i];\\n Deposit storage deposit = deposits[depositId];\\n\\n require(deposit.depositor == msg.sender, \\\"Sender must be the depositor\\\");\\n\\n (\\n bytes32[] memory prunableIntents,\\n uint256 reclaimableAmount\\n ) = _getPrunableIntents(depositId);\\n\\n _pruneIntents(deposit, prunableIntents);\\n\\n returnAmount += deposit.remainingDeposits + reclaimableAmount;\\n \\n deposit.outstandingIntentAmount -= reclaimableAmount;\\n\\n emit DepositWithdrawn(depositId, deposit.depositor, deposit.remainingDeposits + reclaimableAmount);\\n \\n delete deposit.remainingDeposits;\\n _closeDepositIfNecessary(depositId, deposit);\\n }\\n\\n usdc.transfer(msg.sender, returnAmount);\\n }\\n\\n /* ============ Governance Functions ============ */\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the send processor address used for validating and interpreting zk proofs.\\n *\\n * @param _sendProcessor New send proccesor address\\n */\\n function setSendProcessor(IWiseSendProcessor _sendProcessor) external onlyOwner {\\n sendProcessor = _sendProcessor;\\n emit NewSendProcessorSet(address(_sendProcessor));\\n }\\n\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the minimum deposit amount a user can specify for off-ramping.\\n *\\n * @param _minDepositAmount The new minimum deposit amount\\n */\\n function setMinDepositAmount(uint256 _minDepositAmount) external onlyOwner {\\n require(_minDepositAmount != 0, \\\"Minimum deposit cannot be zero\\\");\\n\\n minDepositAmount = _minDepositAmount;\\n emit MinDepositAmountSet(_minDepositAmount);\\n }\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the sustainability fee. This fee is charged to on-rampers upon a successful on-ramp.\\n *\\n * @param _fee The new sustainability fee in precise units (10**18, ie 10% = 1e17)\\n */\\n function setSustainabilityFee(uint256 _fee) external onlyOwner {\\n require(_fee <= MAX_SUSTAINABILITY_FEE, \\\"Fee cannot be greater than max fee\\\");\\n\\n sustainabilityFee = _fee;\\n emit SustainabilityFeeUpdated(_fee);\\n }\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the recepient of sustainability fees.\\n *\\n * @param _feeRecipient The new fee recipient address\\n */\\n function setSustainabilityFeeRecipient(address _feeRecipient) external onlyOwner {\\n require(_feeRecipient != address(0), \\\"Fee recipient cannot be zero address\\\");\\n\\n sustainabilityFeeRecipient = _feeRecipient;\\n emit SustainabilityFeeRecipientUpdated(_feeRecipient);\\n }\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the max amount allowed to be on-ramped in each transaction. To on-ramp more than\\n * this amount a user must make multiple transactions.\\n *\\n * @param _maxOnRampAmount The new max on ramp amount\\n */\\n function setMaxOnRampAmount(uint256 _maxOnRampAmount) external onlyOwner {\\n require(_maxOnRampAmount != 0, \\\"Max on ramp amount cannot be zero\\\");\\n\\n maxOnRampAmount = _maxOnRampAmount;\\n emit MaxOnRampAmountSet(_maxOnRampAmount);\\n }\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the on-ramp cooldown period, once an on-ramp transaction is completed the user must wait this\\n * amount of time before they can signalIntent to on-ramp again.\\n *\\n * @param _onRampCooldownPeriod New on-ramp cooldown period\\n */\\n function setOnRampCooldownPeriod(uint256 _onRampCooldownPeriod) external onlyOwner {\\n onRampCooldownPeriod = _onRampCooldownPeriod;\\n emit OnRampCooldownPeriodSet(_onRampCooldownPeriod);\\n }\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the intent expiration period, after this period elapses an intent can be pruned to prevent\\n * locking up a depositor's funds.\\n *\\n * @param _intentExpirationPeriod New intent expiration period\\n */\\n function setIntentExpirationPeriod(uint256 _intentExpirationPeriod) external onlyOwner {\\n require(_intentExpirationPeriod != 0, \\\"Max intent expiration period cannot be zero\\\");\\n\\n intentExpirationPeriod = _intentExpirationPeriod;\\n emit IntentExpirationPeriodSet(_intentExpirationPeriod);\\n }\\n\\n\\n /* ============ External View Functions ============ */\\n\\n function getDeposit(uint256 _depositId) external view returns (Deposit memory) {\\n return deposits[_depositId];\\n }\\n\\n function getIdCurrentIntentHash(address _account) public view returns (bytes32) {\\n return globalAccount[accountRegistry.getAccountId(_account)].currentIntentHash;\\n }\\n\\n function getIdCurrentIntentHashAsUint(address _account) external view returns (uint256) {\\n return uint256(getIdCurrentIntentHash(_account));\\n }\\n\\n function getLastOnRampTimestamp(address _account) external view returns (uint256) {\\n return globalAccount[accountRegistry.getAccountId(_account)].lastOnrampTimestamp;\\n }\\n\\n function getIntentsWithOnRamperId(bytes32[] calldata _intentHashes) external view returns (IntentWithOnRamperId[] memory) {\\n IntentWithOnRamperId[] memory intentsWithOnRamperId = new IntentWithOnRamperId[](_intentHashes.length);\\n\\n for (uint256 i = 0; i < _intentHashes.length; ++i) {\\n bytes32 intentHash = _intentHashes[i];\\n Intent memory intent = intents[intentHash];\\n intentsWithOnRamperId[i] = IntentWithOnRamperId({\\n intentHash: _intentHashes[i],\\n intent: intent,\\n onRamperId: accountRegistry.getAccountId(intent.onRamper)\\n });\\n }\\n\\n return intentsWithOnRamperId;\\n }\\n\\n function getAccountDeposits(address _account) external view returns (DepositWithAvailableLiquidity[] memory accountDeposits) {\\n uint256[] memory accountDepositIds = globalAccount[accountRegistry.getAccountId(_account)].deposits;\\n accountDeposits = new DepositWithAvailableLiquidity[](accountDepositIds.length);\\n \\n for (uint256 i = 0; i < accountDepositIds.length; ++i) {\\n uint256 depositId = accountDepositIds[i];\\n Deposit memory deposit = deposits[depositId];\\n ( , uint256 reclaimableAmount) = _getPrunableIntents(depositId);\\n\\n accountDeposits[i] = DepositWithAvailableLiquidity({\\n depositId: depositId,\\n depositorId: accountRegistry.getAccountId(deposit.depositor),\\n deposit: deposit,\\n availableLiquidity: deposit.remainingDeposits + reclaimableAmount\\n });\\n }\\n }\\n\\n function getDepositFromIds(uint256[] memory _depositIds) external view returns (DepositWithAvailableLiquidity[] memory depositArray) {\\n depositArray = new DepositWithAvailableLiquidity[](_depositIds.length);\\n\\n for (uint256 i = 0; i < _depositIds.length; ++i) {\\n uint256 depositId = _depositIds[i];\\n Deposit memory deposit = deposits[depositId];\\n ( , uint256 reclaimableAmount) = _getPrunableIntents(depositId);\\n\\n depositArray[i] = DepositWithAvailableLiquidity({\\n depositId: depositId,\\n depositorId: accountRegistry.getAccountId(deposit.depositor),\\n deposit: deposit,\\n availableLiquidity: deposit.remainingDeposits + reclaimableAmount\\n });\\n }\\n\\n return depositArray;\\n }\\n\\n /* ============ Internal Functions ============ */\\n\\n /**\\n * @notice Calculates the intentHash of new intent\\n */\\n function _calculateIntentHash(\\n bytes32 _accountId,\\n uint256 _depositId\\n )\\n internal\\n view\\n virtual\\n returns (bytes32 intentHash)\\n {\\n // Mod with circom prime field to make sure it fits in a 254-bit field\\n uint256 intermediateHash = uint256(keccak256(abi.encodePacked(_accountId, _depositId, block.timestamp)));\\n intentHash = bytes32(intermediateHash % CIRCOM_PRIME_FIELD);\\n }\\n\\n /**\\n * @notice Cycles through all intents currently open on a deposit and sees if any have expired. If they have expired\\n * the outstanding amounts are summed and returned alongside the intentHashes\\n */\\n function _getPrunableIntents(\\n uint256 _depositId\\n )\\n internal\\n view\\n returns(bytes32[] memory prunableIntents, uint256 reclaimedAmount)\\n {\\n bytes32[] memory intentHashes = deposits[_depositId].intentHashes;\\n prunableIntents = new bytes32[](intentHashes.length);\\n\\n for (uint256 i = 0; i < intentHashes.length; ++i) {\\n Intent memory intent = intents[intentHashes[i]];\\n if (intent.intentTimestamp + intentExpirationPeriod < block.timestamp) {\\n prunableIntents[i] = intentHashes[i];\\n reclaimedAmount += intent.amount;\\n }\\n }\\n }\\n\\n function _pruneIntents(Deposit storage _deposit, bytes32[] memory _intents) internal {\\n for (uint256 i = 0; i < _intents.length; ++i) {\\n if (_intents[i] != bytes32(0)) {\\n _pruneIntent(_deposit, _intents[i]);\\n }\\n }\\n }\\n\\n /**\\n * @notice Pruning an intent involves deleting its state from the intents mapping, zeroing out the intendee's currentIntentHash in\\n * their global account mapping, and deleting the intentHash from the deposit's intentHashes array.\\n */\\n function _pruneIntent(Deposit storage _deposit, bytes32 _intentHash) internal {\\n Intent memory intent = intents[_intentHash];\\n\\n delete globalAccount[accountRegistry.getAccountId(intent.onRamper)].currentIntentHash;\\n delete intents[_intentHash];\\n _deposit.intentHashes.removeStorage(_intentHash);\\n\\n emit IntentPruned(_intentHash, intent.deposit);\\n }\\n\\n /**\\n * @notice Removes a deposit if no outstanding intents AND no remaining deposits. Deleting a deposit deletes it from the\\n * deposits mapping and removes tracking it in the user's accounts mapping.\\n */\\n function _closeDepositIfNecessary(uint256 _depositId, Deposit storage _deposit) internal {\\n uint256 openDepositAmount = _deposit.outstandingIntentAmount + _deposit.remainingDeposits;\\n if (openDepositAmount == 0) {\\n globalAccount[accountRegistry.getAccountId(_deposit.depositor)].deposits.removeStorage(_depositId);\\n emit DepositClosed(_depositId, _deposit.depositor);\\n delete deposits[_depositId];\\n }\\n }\\n\\n /**\\n * @notice Checks if sustainability fee has been defined, if so sends fee to the fee recipient and intent amount minus fee\\n * to the on-ramper. If sustainability fee is undefined then full intent amount is transferred to on-ramper.\\n */\\n function _transferFunds(bytes32 _intentHash, Intent memory _intent) internal {\\n uint256 fee;\\n if (sustainabilityFee != 0) {\\n fee = (_intent.amount * sustainabilityFee) / PRECISE_UNIT;\\n usdc.transfer(sustainabilityFeeRecipient, fee);\\n }\\n\\n uint256 onRampAmount = _intent.amount - fee;\\n usdc.transfer(_intent.to, onRampAmount);\\n\\n emit IntentFulfilled(_intentHash, _intent.deposit, _intent.onRamper, _intent.to, onRampAmount, fee);\\n }\\n\\n /**\\n * @notice Validate send payment email and check that it hasn't already been used (done on SendProcessor).\\n * Additionally, we validate that the offRamperId matches the one from the specified intent and that enough\\n * was paid off-chain inclusive of the conversionRate.\\n */\\n function _verifyOnRampProof(\\n IWiseSendProcessor.SendData calldata _data,\\n bytes calldata _verifierSignature\\n )\\n internal\\n returns(Intent storage intent, Deposit storage deposit, bytes32 intentHash)\\n {\\n intentHash = bytes32(_data.intentHash);\\n intent = intents[intentHash];\\n require(intent.onRamper == msg.sender, \\\"Caller must be the on-ramper\\\");\\n\\n deposit = deposits[intent.deposit];\\n\\n (\\n uint256 amount,\\n uint256 timestamp,\\n bytes32 offRamperId,\\n bytes32 onRamperId,\\n bytes32 currencyId\\n ) = sendProcessor.processProof(\\n IWiseSendProcessor.SendProof({\\n public_values: _data,\\n proof: _verifierSignature\\n }),\\n deposit.verifierSigningKey\\n );\\n\\n require(currencyId == deposit.receiveCurrencyId, \\\"Wrong currency sent\\\");\\n require(intent.intentTimestamp <= timestamp, \\\"Intent was not created before send\\\");\\n require(accountRegistry.getAccountInfo(deposit.depositor).offRampId == offRamperId, \\\"Offramper id does not match\\\");\\n require(accountRegistry.getAccountId(intent.onRamper) == onRamperId, \\\"Onramper id does not match\\\");\\n require(amount >= (intent.amount * PRECISE_UNIT) / deposit.conversionRate, \\\"Payment was not enough\\\");\\n }\\n}\\n\",\"keccak256\":\"0x2311ec7238f04b7cdec0a015490052bdf2acc18aedcfe312cec7824210163baa\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseAccountRegistry.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseAccountRegistry {\\n\\n // Each Account is tied to a Wise ID and is represented by an Ethereum address.\\n struct AccountInfo {\\n bytes32 accountId; // User's Wise account ID\\n bytes32 offRampId; // Multi-currency account ID to receive funds\\n bytes32 wiseTagHash; // Hash of user's wise tag account stored on register. Used to verify offramper's wise tag\\n }\\n\\n function getAccountInfo(address _account) external view returns (AccountInfo memory);\\n function getAccountId(address _account) external view returns (bytes32);\\n\\n function isRegisteredUser(address _account) external view returns (bool);\\n \\n function isAllowedUser(address _account, bytes32 _deniedUser) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xfaf30dc7e7dd1a0bce25c0188059b17bde3929fb473570bc8860a82ae97c5b35\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseSendProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseSendProcessor {\\n\\n struct SendData {\\n string endpoint;\\n string host;\\n string transferId;\\n string senderId;\\n string recipientId;\\n string amount;\\n string currencyId;\\n string status;\\n string timestamp;\\n uint256 intentHash;\\n }\\n\\n struct SendProof {\\n SendData public_values;\\n bytes proof;\\n }\\n\\n function processProof(\\n SendProof calldata _proof,\\n address _verifierSigningKey\\n )\\n external\\n returns(uint256, uint256, bytes32, bytes32, bytes32);\\n}\\n\",\"keccak256\":\"0x7ad931dd67d911bad70d61299f5c4208ca68cadcbe1d06a14dcf9fb812074e8b\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523480156200001157600080fd5b506040516200494d3803806200494d8339810160408190526200003491620001dd565b6200003f3362000096565b6001600160a01b038781166080526006879055600786905560098590556008849055600a839055600b80546001600160a01b0319169183169190911790556200008888620000e6565b505050505050505062000263565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620000f062000169565b6001600160a01b0381166200015b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001668162000096565b50565b6000546001600160a01b03163314620001c55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000152565b565b6001600160a01b03811681146200016657600080fd5b600080600080600080600080610100898b031215620001fb57600080fd5b88516200020881620001c7565b60208a01519098506200021b81620001c7565b8097505060408901519550606089015194506080890151935060a0890151925060c0890151915060e08901516200025281620001c7565b809150509295985092959890939650565b6080516146b26200029b600039600081816102e5015281816118d301528181611eb10152818161347c015261352b01526146b26000f3fe608060405234801561001057600080fd5b50600436106102275760003560e01c80637113476211610130578063b3c0cfa4116100b8578063e279d9641161007c578063e279d96414610540578063ecb3dc8814610549578063ecd618f014610552578063eea1d19714610572578063f2fde38b1461058557600080fd5b8063b3c0cfa4146104e1578063b3fa4c01146104f4578063d089e11a14610507578063d55f960d1461051a578063d9478d201461052d57600080fd5b80639021578a116100ff5780639021578a146104025780639087beff1461047e5780639f9fb96814610491578063a1a954b7146104b1578063b02c43d0146104ba57600080fd5b806371134762146103c3578063715018a6146103d657806371a28f69146103de5780638da5cb5b146103f157600080fd5b806342987349116101b3578063534aa07c11610182578063534aa07c1461036e578063560d9716146103815780635dd7651514610394578063645006ca146103a757806366ec8419146103b057600080fd5b8063429873491461031f578063485cc95514610332578063495223e7146103455780635081d9521461034e57600080fd5b80632a80cda3116101fa5780632a80cda314610283578063317dcc9614610296578063392e53cd146102a95780633adba28a146102cd5780633e413bee146102e057600080fd5b80630f1ef98c1461022c578063133de6cb1461025257806314ec32fa14610267578063238c84941461027a575b600080fd5b61023f61023a366004613a23565b610598565b6040519081526020015b60405180910390f35b610265610260366004613a23565b610627565b005b61023f610275366004613a23565b610684565b61023f600a5481565b610265610291366004613a47565b610711565b6102656102a4366004613a47565b6107a3565b6002546102bd90600160a01b900460ff1681565b6040519015158152602001610249565b6102656102db366004613a60565b6107e0565b6103077f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610249565b61026561032d366004613a47565b610ee4565b610265610340366004613a99565b610f85565b61023f60085481565b61036161035c366004613a23565b611018565b6040516102499190613bee565b61026561037c366004613cbb565b6113d8565b61026561038f366004613d2d565b611996565b6102656103a2366004613a47565b611ac5565b61023f60065481565b6102656103be366004613a47565b611b64565b6102656103d1366004613e0d565b611d33565b610265611f26565b6103616103ec366004613e0d565b611f3a565b6000546001600160a01b0316610307565b61044b610410366004613a47565b600560205260009081526040902080546001820154600283015460038401546004909401546001600160a01b03938416949390921692909185565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610249565b61026561048c366004613a47565b612222565b6104a461049f366004613a47565b6122b9565b6040516102499190613eb2565b61023f60095481565b6104cd6104c8366004613a47565b612440565b604051610249989796959493929190613ec5565b61023f6104ef366004613a23565b612520565b610265610502366004613a23565b612531565b600154610307906001600160a01b031681565b610265610528366004613a47565b6125e9565b600b54610307906001600160a01b031681565b61023f60075481565b61023f600c5481565b610565610560366004613f1d565b612809565b6040516102499190613f91565b600254610307906001600160a01b031681565b610265610593366004613a23565b612a00565b60015460405163e0b490f760e01b81526001600160a01b03838116600483015260009260039284929091169063e0b490f790602401602060405180830381865afa1580156105ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060e9190614021565b8152602001908152602001600020600101549050919050565b61062f612a79565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f6e7665a41605edc0d70f4b991d652755f380754eb092d81ef9ab93664778d59e906020015b60405180910390a150565b60015460405163e0b490f760e01b81526001600160a01b03838116600483015260009260039284929091169063e0b490f790602401602060405180830381865afa1580156106d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106fa9190614021565b815260208101919091526040016000205492915050565b610719612a79565b8060000361076e5760405162461bcd60e51b815260206004820152601e60248201527f4d696e696d756d206465706f7369742063616e6e6f74206265207a65726f000060448201526064015b60405180910390fd5b60068190556040518181527fbdde72a6d8d8b42770c9899945ccdce09d0c5c794d3326cdb2d2cca61b12a9fc90602001610679565b6107ab612a79565b60088190556040518181527f88397975d177ce5e18abf3a5fdb8de773e80673d85eeb54f48cfaf688b3d2c3e90602001610679565b600154604051631f5bdf5d60e01b81523360048201526001600160a01b0390911690631f5bdf5d90602401602060405180830381865afa158015610828573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084c919061403a565b6108985760405162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d7573742062652072656769737465726564207573657200006044820152606401610765565b60015460405163e0b490f760e01b81523360048201526000916001600160a01b03169063e0b490f790602401602060405180830381865afa1580156108e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109059190614021565b60008581526004602081905260409182902060015481549351630359b09b60e31b81526001600160a01b039485169381019390935260248301859052939450929190911690631acd84d890604401602060405180830381865afa158015610970573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610994919061403a565b6109e05760405162461bcd60e51b815260206004820181905260248201527f4f6e72616d706572206f6e206465706f7369746f7227732064656e796c6973746044820152606401610765565b6008546000838152600360205260409020600101544291610a0091614072565b1115610a5a5760405162461bcd60e51b8152602060048201526024808201527f4f6e2072616d7020636f6f6c20646f776e20706572696f64206e6f7420656c616044820152631c1cd95960e21b6064820152608401610765565b60008281526003602052604090205415610ab65760405162461bcd60e51b815260206004820152601860248201527f496e74656e74207374696c6c206f75747374616e64696e6700000000000000006044820152606401610765565b600154815460405163e0b490f760e01b81526001600160a01b0391821660048201528492919091169063e0b490f790602401602060405180830381865afa158015610b05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b299190614021565b03610b765760405162461bcd60e51b815260206004820152601e60248201527f53656e6465722063616e6e6f7420626520746865206465706f7369746f7200006044820152606401610765565b80546001600160a01b0316610bc65760405162461bcd60e51b815260206004820152601660248201527511195c1bdcda5d08191bd95cc81b9bdd08195e1a5cdd60521b6044820152606401610765565b60008411610c255760405162461bcd60e51b815260206004820152602660248201527f5369676e616c656420616d6f756e74206d75737420626520677265617465722060448201526507468616e20360d41b6064820152608401610765565b600754841115610c945760405162461bcd60e51b815260206004820152603460248201527f5369676e616c656420616d6f756e74206d757374206265206c657373207468616044820152731b881b585e081bdb8b5c985b5c08185b5bdd5b9d60621b6064820152608401610765565b6001600160a01b038316610cea5760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f742073656e6420746f207a65726f206164647265737300000000006044820152606401610765565b6000610cf68387612ad3565b90508482600501541015610dab57600080610d1088612b3e565b9150915086818560050154610d259190614072565b1015610d6a5760405162461bcd60e51b81526020600482015260146024820152734e6f7420656e6f756768206c697175696469747960601b6044820152606401610765565b610d748483612ce5565b80846005016000828254610d889190614072565b9250508190555080846006016000828254610da39190614085565b909155505050505b6040805160a0810182523381526001600160a01b0386811660208084019182528385018b8152606085018b8152426080870190815260008981526005808652898220985189549089166001600160a01b0319918216178a55965160018a01805491909916971696909617909655915160028701555160038087019190915590516004909501949094558783529290925291822083905583018054879290610e53908490614085565b9250508190555084826006016000828254610e6e9190614072565b9091555050600882018054600181018255600091825260209182902001829055604080516001600160a01b038716815291820187905242908201528390879083907f1a1292e170a0f000ccf956afba79bee0f9ec1d81f3f901c1d4d11e1f336aae109060600160405180910390a4505050505050565b610eec612a79565b80600003610f505760405162461bcd60e51b815260206004820152602b60248201527f4d617820696e74656e742065787069726174696f6e20706572696f642063616e60448201526a6e6f74206265207a65726f60a81b6064820152608401610765565b60098190556040518181527f55e3f6b95de9a0ec782f892e93fafe4e56be0696df204ddf8e0a40a9a713a80390602001610679565b610f8d612a79565b600254600160a01b900460ff1615610fdd5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610765565b600180546001600160a01b039384166001600160a01b0319909116179055600280546001600160a81b0319169190921617600160a01b179055565b60015460405163e0b490f760e01b81526001600160a01b0383811660048301526060926000926003928492169063e0b490f790602401602060405180830381865afa15801561106b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108f9190614021565b81526020019081526020016000206002018054806020026020016040519081016040528092919081815260200182805480156110ea57602002820191906000526020600020905b8154815260200190600101908083116110d6575b5050505050905080516001600160401b0381111561110a5761110a613d9e565b60405190808252806020026020018201604052801561114357816020015b6111306138cd565b8152602001906001900390816111285790505b50915060005b81518110156113d157600082828151811061116657611166614098565b60209081029190910181015160008181526004835260408082208151610120810190925280546001600160a01b0316825260018101805494965092949193909291840191906111b4906140ae565b80601f01602080910402602001604051908101604052809291908181526020018280546111e0906140ae565b801561122d5780601f106112025761010080835404028352916020019161122d565b820191906000526020600020905b81548152906001019060200180831161121057829003601f168201915b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882018054806020026020016040519081016040528092919081815260200182805480156112e657602002820191906000526020600020905b8154815260200190600101908083116112d2575b505050505081525050905060006112fc83612b3e565b604080516080810182528681526001548651925163e0b490f760e01b81526001600160a01b039384166004820152939550909350602084019291169063e0b490f790602401602060405180830381865afa15801561135e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113829190614021565b8152602001838152602001828460a0015161139d9190614072565b8152508685815181106113b2576113b2614098565b6020026020010181905250505050806113ca906140e2565b9050611149565b5050919050565b600154604051631f5bdf5d60e01b81523360048201526001600160a01b0390911690631f5bdf5d90602401602060405180830381865afa158015611420573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611444919061403a565b6114905760405162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d7573742062652072656769737465726564207573657200006044820152606401610765565b600154604051630f6a21fd60e31b81523360048201526000916001600160a01b031690637b510fe890602401606060405180830381865afa1580156114d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114fd91906140fb565b8051600090815260036020908152604090912090820151919250906115645760405162461bcd60e51b815260206004820181905260248201527f4d7573742062652072656769737465726564206173206f66662072616d7065726044820152606401610765565b8160400151888860405160200161157c929190614156565b60405160208183030381529060405280519060200120146115f35760405162461bcd60e51b815260206004820152602b60248201527f576973652074616720646f6573206e6f74206d6174636820726567697374657260448201526a656420776973652074616760a81b6064820152608401610765565b60028101546005116116475760405162461bcd60e51b815260206004820152601e60248201527f4d6178696d756d206465706f73697420616d6f756e74207265616368656400006044820152606401610765565b6006548510156116b85760405162461bcd60e51b815260206004820152603660248201527f4465706f73697420616d6f756e74206d757374206265206772656174657220746044820152751a185b881b5a5b8819195c1bdcda5d08185b5bdd5b9d60521b6064820152608401610765565b600084116117165760405162461bcd60e51b815260206004820152602560248201527f5265636569766520616d6f756e74206d75737420626520677265617465722074604482015264068616e20360dc1b6064820152608401610765565b60008461172b670de0b6b3a764000088614185565b61173591906141b2565b600c8054919250600091908261174a836140e2565b9091555060028401805460018101825560009182526020918290200182905560408051610120810182523381528151601f8e018490048402810184019092528c8252929350828201918d908d908190840183828082843760009201829052509385525050506001600160a01b03881660208084019190915260408084018c9052606084018d9052608084018c905260a0840183905260c084018790528051838152918201905260e090920191905090526000828152600460209081526040909120825181546001600160a01b0319166001600160a01b0390911617815590820151600182019061183a908261420c565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e0820151600782015561010082015180516118af9160088401916020909101906138f9565b50506040516323b872dd60e01b8152336004820152306024820152604481018990527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691506323b872dd906064016020604051808303816000875af1158015611925573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611949919061403a565b50835160408051898152602081018590528a929184917f94c4b6f8843ea372709c89bc4a9ed85ef74ab10a68713ffdddc31716a76a6c95910160405180910390a450505050505050505050565b60008060006119a6868686612d47565b6040805160a08101825284546001600160a01b0390811682526001860154166020820152600285015491810191909152600384015460608201526004909301546080840152919450925090506119fc8282613160565b8260600151826006016000828254611a149190614085565b9091555050600154835160405163e0b490f760e01b81526001600160a01b039182166004820152429260039260009291169063e0b490f790602401602060405180830381865afa158015611a6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a909190614021565b815260200190815260200160002060010181905550611ab38360400151836132a9565b611abd818461341f565b505050505050565b611acd612a79565b66b1a2bc2ec50000811115611b2f5760405162461bcd60e51b815260206004820152602260248201527f4665652063616e6e6f742062652067726561746572207468616e206d61782066604482015261656560f01b6064820152608401610765565b600a8190556040518181527f44f48e1b871e6db1e909a7b253b054b7150a0b4ddf4d59b159c827d82e72567090602001610679565b6000818152600560209081526040808320815160a08101835281546001600160a01b03908116825260018301548116828601526002830154828501819052600384015460608401526004938401546080840152865291909352922081519192909116611c0a5760405162461bcd60e51b8152602060048201526015602482015274125b9d195b9d08191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606401610765565b80546001600160a01b03163314611c635760405162461bcd60e51b815260206004820152601c60248201527f43616c6c6572206d75737420626520746865206465706f7369746f72000000006044820152606401610765565b611c6d8184613160565b8160600151816006016000828254611c859190614085565b9091555050600154825160405163e0b490f760e01b81526001600160a01b039182166004820152429260039260009291169063e0b490f790602401602060405180830381865afa158015611cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d019190614021565b815260200190815260200160002060010181905550611d248260400151826132a9565b611d2e838361341f565b505050565b6000805b8251811015611e94576000838281518110611d5457611d54614098565b6020908102919091018101516000818152600490925260409091208054919250906001600160a01b03163314611dcc5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206d75737420626520746865206465706f7369746f72000000006044820152606401610765565b600080611dd884612b3e565b91509150611de68383612ce5565b808360050154611df69190614072565b611e009087614072565b955080836006016000828254611e169190614085565b9091555050825460058401546001600160a01b039091169085907fae1f357660ab777dcfd38c0ab6357834684ec26289ecfa07ec65dbf6c3c6431290611e5d908590614072565b60405190815260200160405180910390a360006005840155611e7f84846132a9565b5050505080611e8d906140e2565b9050611d37565b5060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015611f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2e919061403a565b611f2e612a79565b611f3860006135fd565b565b606081516001600160401b03811115611f5557611f55613d9e565b604051908082528060200260200182016040528015611f8e57816020015b611f7b6138cd565b815260200190600190039081611f735790505b50905060005b825181101561221c576000838281518110611fb157611fb1614098565b60209081029190910181015160008181526004835260408082208151610120810190925280546001600160a01b031682526001810180549496509294919390929184019190611fff906140ae565b80601f016020809104026020016040519081016040528092919081815260200182805461202b906140ae565b80156120785780601f1061204d57610100808354040283529160200191612078565b820191906000526020600020905b81548152906001019060200180831161205b57829003601f168201915b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820180548060200260200160405190810160405280929190818152602001828054801561213157602002820191906000526020600020905b81548152602001906001019080831161211d575b5050505050815250509050600061214783612b3e565b604080516080810182528681526001548651925163e0b490f760e01b81526001600160a01b039384166004820152939550909350602084019291169063e0b490f790602401602060405180830381865afa1580156121a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121cd9190614021565b8152602001838152602001828460a001516121e89190614072565b8152508585815181106121fd576121fd614098565b602002602001018190525050505080612215906140e2565b9050611f94565b50919050565b61222a612a79565b806000036122845760405162461bcd60e51b815260206004820152602160248201527f4d6178206f6e2072616d7020616d6f756e742063616e6e6f74206265207a65726044820152606f60f81b6064820152608401610765565b60078190556040518181527fcab6b49ca21dd111cf4a55d507bbe89dd12d69216e28247060d4b2163ca41b3990602001610679565b6122c1613944565b6000828152600460209081526040918290208251610120810190935280546001600160a01b0316835260018101805491928401916122fe906140ae565b80601f016020809104026020016040519081016040528092919081815260200182805461232a906140ae565b80156123775780601f1061234c57610100808354040283529160200191612377565b820191906000526020600020905b81548152906001019060200180831161235a57829003601f168201915b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820180548060200260200160405190810160405280929190818152602001828054801561243057602002820191906000526020600020905b81548152602001906001019080831161241c575b5050505050815250509050919050565b600460205260009081526040902080546001820180546001600160a01b03909216929161246c906140ae565b80601f0160208091040260200160405190810160405280929190818152602001828054612498906140ae565b80156124e55780601f106124ba576101008083540402835291602001916124e5565b820191906000526020600020905b8154815290600101906020018083116124c857829003601f168201915b5050506002840154600385015460048601546005870154600688015460079098015496976001600160a01b0390941696929550909350919088565b600061252b82610684565b92915050565b612539612a79565b6001600160a01b03811661259b5760405162461bcd60e51b8152602060048201526024808201527f46656520726563697069656e742063616e6e6f74206265207a65726f206164646044820152637265737360e01b6064820152608401610765565b600b80546001600160a01b0319166001600160a01b0383169081179091556040519081527f594ad6ee98bfc0c73e6d15fd4e762502f359e05d26907b7fa1ff82eb5e99f6e490602001610679565b6000818152600560209081526040808320815160a08101835281546001600160a01b039081168252600183015416938101939093526002810154918301919091526003810154606083015260040154608082018190529091036126865760405162461bcd60e51b8152602060048201526015602482015274125b9d195b9d08191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606401610765565b60015460405163e0b490f760e01b81523360048201526001600160a01b039091169063e0b490f790602401602060405180830381865afa1580156126ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126f29190614021565b600154825160405163e0b490f760e01b81526001600160a01b03918216600482015291169063e0b490f790602401602060405180830381865afa15801561273d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127619190614021565b146127ae5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206d75737420626520746865206f6e2d72616d706572000000006044820152606401610765565b60408082015160009081526004602052206127c98184613160565b81606001518160050160008282546127e19190614072565b909155505060608201516006820180546000906127ff908490614085565b9091555050505050565b60606000826001600160401b0381111561282557612825613d9e565b60405190808252806020026020018201604052801561289f57816020015b61288c60408051606080820183526000808352835160a0810185528181526020818101839052948101829052918201819052608082015290918201908152600060209091015290565b8152602001906001900390816128435790505b50905060005b838110156129f85760008585838181106128c1576128c1614098565b60209081029290920135600081815260058452604090819020815160a08101835281546001600160a01b0390811682526001830154169581019590955260028101548583015260038101546060808701919091526004909101546080860152815190810190915290935090508088888681811061294057612940614098565b60209081029290920135835250810183905260015483516040805163e0b490f760e01b81526001600160a01b03928316600482015293019291169063e0b490f790602401602060405180830381865afa1580156129a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c59190614021565b8152508484815181106129da576129da614098565b60200260200101819052505050806129f1906140e2565b90506128a5565b509392505050565b612a08612a79565b6001600160a01b038116612a6d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610765565b612a76816135fd565b50565b6000546001600160a01b03163314611f385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610765565b6040805160208101849052908101829052426060820152600090819060800160408051601f1981840301815291905280516020909101209050612b367f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001826142cb565b949350505050565b60008181526004602090815260408083206008018054825181850281018501909352808352606094938493929190830182828015612b9b57602002820191906000526020600020905b815481526020019060010190808311612b87575b5050505050905080516001600160401b03811115612bbb57612bbb613d9e565b604051908082528060200260200182016040528015612be4578160200160208202803683370190505b50925060005b8151811015612cde57600060056000848481518110612c0b57612c0b614098565b6020908102919091018101518252818101929092526040908101600020815160a08101835281546001600160a01b039081168252600183015416938101939093526002810154918301919091526003810154606083015260040154608082018190526009549192504291612c7e91614072565b1015612ccd57828281518110612c9657612c96614098565b6020026020010151858381518110612cb057612cb0614098565b60209081029190910101526060810151612cca9085614072565b93505b50612cd7816140e2565b9050612bea565b5050915091565b60005b8151811015611d2e576000801b828281518110612d0757612d07614098565b602002602001015114612d3757612d3783838381518110612d2a57612d2a614098565b6020026020010151613160565b612d40816140e2565b9050612ce8565b610120830135600081815260056020526040812080549092906001600160a01b03163314612db75760405162461bcd60e51b815260206004820152601c60248201527f43616c6c6572206d75737420626520746865206f6e2d72616d706572000000006044820152606401610765565b60028084015460009081526004602052604080822092548151808301909252929450909182918291829182916001600160a01b03169063f20333c19080612dfd8f61434e565b81526020018d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505091525060028a01546040516001600160e01b031960e085901b168152612e6a92916001600160a01b0316906004016144ce565b60a0604051808303816000875af1158015612e89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ead9190614626565b9450945094509450945086600401548114612f005760405162461bcd60e51b815260206004820152601360248201527215dc9bdb99c818dd5c9c995b98de481cd95b9d606a1b6044820152606401610765565b8388600401541115612f5f5760405162461bcd60e51b815260206004820152602260248201527f496e74656e7420776173206e6f742063726561746564206265666f72652073656044820152611b9960f21b6064820152608401610765565b6001548754604051630f6a21fd60e31b81526001600160a01b03918216600482015285929190911690637b510fe890602401606060405180830381865afa158015612fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd291906140fb565b60200151146130235760405162461bcd60e51b815260206004820152601b60248201527f4f666672616d70657220696420646f6573206e6f74206d6174636800000000006044820152606401610765565b600154885460405163e0b490f760e01b81526001600160a01b0391821660048201528492919091169063e0b490f790602401602060405180830381865afa158015613072573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130969190614021565b146130e35760405162461bcd60e51b815260206004820152601a60248201527f4f6e72616d70657220696420646f6573206e6f74206d617463680000000000006044820152606401610765565b8660070154670de0b6b3a764000089600301546131009190614185565b61310a91906141b2565b8510156131525760405162461bcd60e51b81526020600482015260166024820152750a0c2f2dacadce840eec2e640dcdee840cadcdeeaced60531b6044820152606401610765565b505050505093509350939050565b6000818152600560209081526040808320815160a08101835281546001600160a01b03908116808352600180850154831696840196909652600284015483860152600380850154606085015260049485015460808501529554945163e0b490f760e01b815293840152909492169063e0b490f790602401602060405180830381865afa1580156131f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132189190614021565b8152602080820192909252604090810160009081208190558481526005909252812080546001600160a01b031990811682556001820180549091169055600281018290556003810182905560040155613274600884018361364d565b604080820151905183907fe8a865b4bab023c399cbd1f2cdd0df2199beb6e5012a4bd2d7691cf7e4199d5a90600090a3505050565b6000816005015482600601546132bf9190614072565b905080600003611d2e57600154825460405163e0b490f760e01b81526001600160a01b039182166004820152613365928692600392600092919091169063e0b490f790602401602060405180830381865afa158015613322573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133469190614021565b815260200190815260200160002060020161377590919063ffffffff16565b8154604080518581526001600160a01b0390921660208301527f8ac07cc6e38c6222dd0309c80353c1962354bacf222b825d7401cc80e93ff3cc910160405180910390a1600083815260046020526040812080546001600160a01b0319168155906133d360018301826139a5565b6002820180546001600160a01b0319169055600060038301819055600483018190556005830181905560068301819055600783018190556134189060088401906139df565b5050505050565b6000600a546000146134eb57670de0b6b3a7640000600a5483606001516134469190614185565b61345091906141b2565b600b5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156134c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134e9919061403a565b505b60008183606001516134fd9190614085565b602084015160405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015613574573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613598919061403a565b50825160408085015160208087015183516001600160a01b03918216815291820186905292810186905291909216919086907ffa03438194e61c243c6bb5349f1e1dc674431b86f119b5e3b2b327bc43446bce9060600160405180910390a450505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806136a98480548060200260200160405190810160405280929190818152602001828054801561369e57602002820191906000526020600020905b81548152602001906001019080831161368a575b50505050508461381a565b91509150806136f25760405162461bcd60e51b8152602060048201526015602482015274313cba32b99999103737ba1034b71030b93930bc9760591b6044820152606401610765565b835460009061370390600190614085565b90508083146137485784818154811061371e5761371e614098565b906000526020600020015485848154811061373b5761373b614098565b6000918252602090912001555b8480548061375857613758614666565b600190038181906000526020600020016000905590555050505050565b6000806137d1848054806020026020016040519081016040528092919081815260200182805480156137c657602002820191906000526020600020905b8154815260200190600101908083116137b2575b50505050508461387d565b91509150806136f25760405162461bcd60e51b81526020600482015260156024820152743ab4b73a191a9b103737ba1034b71030b93930bc9760591b6044820152606401610765565b81516000908190815b8181101561386a578486828151811061383e5761383e614098565b602002602001015103613858579250600191506138769050565b80613862816140e2565b915050613823565b50600019600092509250505b9250929050565b81516000908190815b8181101561386a57848682815181106138a1576138a1614098565b6020026020010151036138bb579250600191506138769050565b806138c5816140e2565b915050613886565b60408051608081018252600080825260208201529081016138ec613944565b8152602001600081525090565b828054828255906000526020600020908101928215613934579160200282015b82811115613934578251825591602001919060010190613919565b506139409291506139f9565b5090565b60405180610120016040528060006001600160a01b031681526020016060815260200160006001600160a01b031681526020016000815260200160008019168152602001600081526020016000815260200160008152602001606081525090565b5080546139b1906140ae565b6000825580601f106139c1575050565b601f016020900490600052602060002090810190612a7691906139f9565b5080546000825590600052602060002090810190612a7691905b5b8082111561394057600081556001016139fa565b6001600160a01b0381168114612a7657600080fd5b600060208284031215613a3557600080fd5b8135613a4081613a0e565b9392505050565b600060208284031215613a5957600080fd5b5035919050565b600080600060608486031215613a7557600080fd5b83359250602084013591506040840135613a8e81613a0e565b809150509250925092565b60008060408385031215613aac57600080fd5b8235613ab781613a0e565b91506020830135613ac781613a0e565b809150509250929050565b6000815180845260005b81811015613af857602081850181015186830182015201613adc565b506000602082860101526020601f19601f83011685010191505092915050565b600081518084526020808501945080840160005b83811015613b4857815187529582019590820190600101613b2c565b509495945050505050565b80516001600160a01b0316825260006101206020830151816020860152613b7c82860182613ad2565b9150506040830151613b9960408601826001600160a01b03169052565b50606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e083015160e08501526101008084015185830382870152613be48382613b18565b9695505050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015613c6c57603f1989840301855281516080815185528882015189860152878201518189870152613c4b82870182613b53565b60609384015196909301959095525094870194925090860190600101613c15565b509098975050505050505050565b60008083601f840112613c8c57600080fd5b5081356001600160401b03811115613ca357600080fd5b60208301915083602082850101111561387657600080fd5b60008060008060008060a08789031215613cd457600080fd5b86356001600160401b03811115613cea57600080fd5b613cf689828a01613c7a565b9097509550506020870135935060408701359250606087013591506080870135613d1f81613a0e565b809150509295509295509295565b600080600060408486031215613d4257600080fd5b83356001600160401b0380821115613d5957600080fd5b908501906101408288031215613d6e57600080fd5b90935060208501359080821115613d8457600080fd5b50613d9186828701613c7a565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405161014081016001600160401b0381118282101715613dd757613dd7613d9e565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613e0557613e05613d9e565b604052919050565b60006020808385031215613e2057600080fd5b82356001600160401b0380821115613e3757600080fd5b818501915085601f830112613e4b57600080fd5b813581811115613e5d57613e5d613d9e565b8060051b9150613e6e848301613ddd565b8181529183018401918481019088841115613e8857600080fd5b938501935b83851015613ea657843582529385019390850190613e8d565b98975050505050505050565b602081526000613a406020830184613b53565b6001600160a01b03898116825261010060208301819052600091613eeb8483018c613ad2565b9916604084015250506060810195909552608085019390935260a084019190915260c083015260e09091015292915050565b60008060208385031215613f3057600080fd5b82356001600160401b0380821115613f4757600080fd5b818501915085601f830112613f5b57600080fd5b813581811115613f6a57600080fd5b8660208260051b8501011115613f7f57600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b82811015614014578151805185528681015180516001600160a01b039081168988015281890151168787015286810151606080880191909152810151608080880191909152015160a086015285015160c085015260e09093019290850190600101613fae565b5091979650505050505050565b60006020828403121561403357600080fd5b5051919050565b60006020828403121561404c57600080fd5b81518015158114613a4057600080fd5b634e487b7160e01b600052601160045260246000fd5b8082018082111561252b5761252b61405c565b8181038181111561252b5761252b61405c565b634e487b7160e01b600052603260045260246000fd5b600181811c908216806140c257607f821691505b60208210810361221c57634e487b7160e01b600052602260045260246000fd5b6000600182016140f4576140f461405c565b5060010190565b60006060828403121561410d57600080fd5b604051606081018181106001600160401b038211171561412f5761412f613d9e565b80604052508251815260208301516020820152604083015160408201528091505092915050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b808202811582820484141761252b5761252b61405c565b634e487b7160e01b600052601260045260246000fd5b6000826141c1576141c161419c565b500490565b601f821115611d2e57600081815260208120601f850160051c810160208610156141ed5750805b601f850160051c820191505b81811015611abd578281556001016141f9565b81516001600160401b0381111561422557614225613d9e565b6142398161423384546140ae565b846141c6565b602080601f83116001811461426e57600084156142565750858301515b600019600386901b1c1916600185901b178555611abd565b600085815260208120601f198616915b8281101561429d5788860151825594840194600190910190840161427e565b50858210156142bb5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000826142da576142da61419c565b500690565b600082601f8301126142f057600080fd5b81356001600160401b0381111561430957614309613d9e565b61431c601f8201601f1916602001613ddd565b81815284602083860101111561433157600080fd5b816020850160208301376000918101602001919091529392505050565b6000610140823603121561436157600080fd5b614369613db4565b82356001600160401b038082111561438057600080fd5b61438c368387016142df565b835260208501359150808211156143a257600080fd5b6143ae368387016142df565b602084015260408501359150808211156143c757600080fd5b6143d3368387016142df565b604084015260608501359150808211156143ec57600080fd5b6143f8368387016142df565b6060840152608085013591508082111561441157600080fd5b61441d368387016142df565b608084015260a085013591508082111561443657600080fd5b614442368387016142df565b60a084015260c085013591508082111561445b57600080fd5b614467368387016142df565b60c084015260e085013591508082111561448057600080fd5b61448c368387016142df565b60e0840152610100915081850135818111156144a757600080fd5b6144b3368288016142df565b92840192909252505061012092830135928101929092525090565b604081526000835160408084015280516101408060808601526144f56101c0860183613ad2565b91506020830151607f19808785030160a08801526145138483613ad2565b935060408501519150808785030160c08801526145308483613ad2565b935060608501519150808785030160e088015261454d8483613ad2565b93506080850151915061010081888603018189015261456c8584613ad2565b945060a086015192506101208289870301818a015261458b8685613ad2565b955060c087015193508289870301858a01526145a78685613ad2565b955060e0870151945082898703016101608a01526145c58686613ad2565b955081870151945082898703016101808a01526145e28686613ad2565b9601516101a0890152505050506020860151848303603f1901606086015291905061460d8183613ad2565b92505050613a4060208301846001600160a01b03169052565b600080600080600060a0868803121561463e57600080fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220e73047b166610e8f47090fb36d9adea76ccf223d5d22f65c8ecedd7f9ee46b8b64736f6c63430008120033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102275760003560e01c80637113476211610130578063b3c0cfa4116100b8578063e279d9641161007c578063e279d96414610540578063ecb3dc8814610549578063ecd618f014610552578063eea1d19714610572578063f2fde38b1461058557600080fd5b8063b3c0cfa4146104e1578063b3fa4c01146104f4578063d089e11a14610507578063d55f960d1461051a578063d9478d201461052d57600080fd5b80639021578a116100ff5780639021578a146104025780639087beff1461047e5780639f9fb96814610491578063a1a954b7146104b1578063b02c43d0146104ba57600080fd5b806371134762146103c3578063715018a6146103d657806371a28f69146103de5780638da5cb5b146103f157600080fd5b806342987349116101b3578063534aa07c11610182578063534aa07c1461036e578063560d9716146103815780635dd7651514610394578063645006ca146103a757806366ec8419146103b057600080fd5b8063429873491461031f578063485cc95514610332578063495223e7146103455780635081d9521461034e57600080fd5b80632a80cda3116101fa5780632a80cda314610283578063317dcc9614610296578063392e53cd146102a95780633adba28a146102cd5780633e413bee146102e057600080fd5b80630f1ef98c1461022c578063133de6cb1461025257806314ec32fa14610267578063238c84941461027a575b600080fd5b61023f61023a366004613a23565b610598565b6040519081526020015b60405180910390f35b610265610260366004613a23565b610627565b005b61023f610275366004613a23565b610684565b61023f600a5481565b610265610291366004613a47565b610711565b6102656102a4366004613a47565b6107a3565b6002546102bd90600160a01b900460ff1681565b6040519015158152602001610249565b6102656102db366004613a60565b6107e0565b6103077f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610249565b61026561032d366004613a47565b610ee4565b610265610340366004613a99565b610f85565b61023f60085481565b61036161035c366004613a23565b611018565b6040516102499190613bee565b61026561037c366004613cbb565b6113d8565b61026561038f366004613d2d565b611996565b6102656103a2366004613a47565b611ac5565b61023f60065481565b6102656103be366004613a47565b611b64565b6102656103d1366004613e0d565b611d33565b610265611f26565b6103616103ec366004613e0d565b611f3a565b6000546001600160a01b0316610307565b61044b610410366004613a47565b600560205260009081526040902080546001820154600283015460038401546004909401546001600160a01b03938416949390921692909185565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610249565b61026561048c366004613a47565b612222565b6104a461049f366004613a47565b6122b9565b6040516102499190613eb2565b61023f60095481565b6104cd6104c8366004613a47565b612440565b604051610249989796959493929190613ec5565b61023f6104ef366004613a23565b612520565b610265610502366004613a23565b612531565b600154610307906001600160a01b031681565b610265610528366004613a47565b6125e9565b600b54610307906001600160a01b031681565b61023f60075481565b61023f600c5481565b610565610560366004613f1d565b612809565b6040516102499190613f91565b600254610307906001600160a01b031681565b610265610593366004613a23565b612a00565b60015460405163e0b490f760e01b81526001600160a01b03838116600483015260009260039284929091169063e0b490f790602401602060405180830381865afa1580156105ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060e9190614021565b8152602001908152602001600020600101549050919050565b61062f612a79565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f6e7665a41605edc0d70f4b991d652755f380754eb092d81ef9ab93664778d59e906020015b60405180910390a150565b60015460405163e0b490f760e01b81526001600160a01b03838116600483015260009260039284929091169063e0b490f790602401602060405180830381865afa1580156106d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106fa9190614021565b815260208101919091526040016000205492915050565b610719612a79565b8060000361076e5760405162461bcd60e51b815260206004820152601e60248201527f4d696e696d756d206465706f7369742063616e6e6f74206265207a65726f000060448201526064015b60405180910390fd5b60068190556040518181527fbdde72a6d8d8b42770c9899945ccdce09d0c5c794d3326cdb2d2cca61b12a9fc90602001610679565b6107ab612a79565b60088190556040518181527f88397975d177ce5e18abf3a5fdb8de773e80673d85eeb54f48cfaf688b3d2c3e90602001610679565b600154604051631f5bdf5d60e01b81523360048201526001600160a01b0390911690631f5bdf5d90602401602060405180830381865afa158015610828573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084c919061403a565b6108985760405162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d7573742062652072656769737465726564207573657200006044820152606401610765565b60015460405163e0b490f760e01b81523360048201526000916001600160a01b03169063e0b490f790602401602060405180830381865afa1580156108e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109059190614021565b60008581526004602081905260409182902060015481549351630359b09b60e31b81526001600160a01b039485169381019390935260248301859052939450929190911690631acd84d890604401602060405180830381865afa158015610970573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610994919061403a565b6109e05760405162461bcd60e51b815260206004820181905260248201527f4f6e72616d706572206f6e206465706f7369746f7227732064656e796c6973746044820152606401610765565b6008546000838152600360205260409020600101544291610a0091614072565b1115610a5a5760405162461bcd60e51b8152602060048201526024808201527f4f6e2072616d7020636f6f6c20646f776e20706572696f64206e6f7420656c616044820152631c1cd95960e21b6064820152608401610765565b60008281526003602052604090205415610ab65760405162461bcd60e51b815260206004820152601860248201527f496e74656e74207374696c6c206f75747374616e64696e6700000000000000006044820152606401610765565b600154815460405163e0b490f760e01b81526001600160a01b0391821660048201528492919091169063e0b490f790602401602060405180830381865afa158015610b05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b299190614021565b03610b765760405162461bcd60e51b815260206004820152601e60248201527f53656e6465722063616e6e6f7420626520746865206465706f7369746f7200006044820152606401610765565b80546001600160a01b0316610bc65760405162461bcd60e51b815260206004820152601660248201527511195c1bdcda5d08191bd95cc81b9bdd08195e1a5cdd60521b6044820152606401610765565b60008411610c255760405162461bcd60e51b815260206004820152602660248201527f5369676e616c656420616d6f756e74206d75737420626520677265617465722060448201526507468616e20360d41b6064820152608401610765565b600754841115610c945760405162461bcd60e51b815260206004820152603460248201527f5369676e616c656420616d6f756e74206d757374206265206c657373207468616044820152731b881b585e081bdb8b5c985b5c08185b5bdd5b9d60621b6064820152608401610765565b6001600160a01b038316610cea5760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f742073656e6420746f207a65726f206164647265737300000000006044820152606401610765565b6000610cf68387612ad3565b90508482600501541015610dab57600080610d1088612b3e565b9150915086818560050154610d259190614072565b1015610d6a5760405162461bcd60e51b81526020600482015260146024820152734e6f7420656e6f756768206c697175696469747960601b6044820152606401610765565b610d748483612ce5565b80846005016000828254610d889190614072565b9250508190555080846006016000828254610da39190614085565b909155505050505b6040805160a0810182523381526001600160a01b0386811660208084019182528385018b8152606085018b8152426080870190815260008981526005808652898220985189549089166001600160a01b0319918216178a55965160018a01805491909916971696909617909655915160028701555160038087019190915590516004909501949094558783529290925291822083905583018054879290610e53908490614085565b9250508190555084826006016000828254610e6e9190614072565b9091555050600882018054600181018255600091825260209182902001829055604080516001600160a01b038716815291820187905242908201528390879083907f1a1292e170a0f000ccf956afba79bee0f9ec1d81f3f901c1d4d11e1f336aae109060600160405180910390a4505050505050565b610eec612a79565b80600003610f505760405162461bcd60e51b815260206004820152602b60248201527f4d617820696e74656e742065787069726174696f6e20706572696f642063616e60448201526a6e6f74206265207a65726f60a81b6064820152608401610765565b60098190556040518181527f55e3f6b95de9a0ec782f892e93fafe4e56be0696df204ddf8e0a40a9a713a80390602001610679565b610f8d612a79565b600254600160a01b900460ff1615610fdd5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610765565b600180546001600160a01b039384166001600160a01b0319909116179055600280546001600160a81b0319169190921617600160a01b179055565b60015460405163e0b490f760e01b81526001600160a01b0383811660048301526060926000926003928492169063e0b490f790602401602060405180830381865afa15801561106b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108f9190614021565b81526020019081526020016000206002018054806020026020016040519081016040528092919081815260200182805480156110ea57602002820191906000526020600020905b8154815260200190600101908083116110d6575b5050505050905080516001600160401b0381111561110a5761110a613d9e565b60405190808252806020026020018201604052801561114357816020015b6111306138cd565b8152602001906001900390816111285790505b50915060005b81518110156113d157600082828151811061116657611166614098565b60209081029190910181015160008181526004835260408082208151610120810190925280546001600160a01b0316825260018101805494965092949193909291840191906111b4906140ae565b80601f01602080910402602001604051908101604052809291908181526020018280546111e0906140ae565b801561122d5780601f106112025761010080835404028352916020019161122d565b820191906000526020600020905b81548152906001019060200180831161121057829003601f168201915b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882018054806020026020016040519081016040528092919081815260200182805480156112e657602002820191906000526020600020905b8154815260200190600101908083116112d2575b505050505081525050905060006112fc83612b3e565b604080516080810182528681526001548651925163e0b490f760e01b81526001600160a01b039384166004820152939550909350602084019291169063e0b490f790602401602060405180830381865afa15801561135e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113829190614021565b8152602001838152602001828460a0015161139d9190614072565b8152508685815181106113b2576113b2614098565b6020026020010181905250505050806113ca906140e2565b9050611149565b5050919050565b600154604051631f5bdf5d60e01b81523360048201526001600160a01b0390911690631f5bdf5d90602401602060405180830381865afa158015611420573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611444919061403a565b6114905760405162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d7573742062652072656769737465726564207573657200006044820152606401610765565b600154604051630f6a21fd60e31b81523360048201526000916001600160a01b031690637b510fe890602401606060405180830381865afa1580156114d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114fd91906140fb565b8051600090815260036020908152604090912090820151919250906115645760405162461bcd60e51b815260206004820181905260248201527f4d7573742062652072656769737465726564206173206f66662072616d7065726044820152606401610765565b8160400151888860405160200161157c929190614156565b60405160208183030381529060405280519060200120146115f35760405162461bcd60e51b815260206004820152602b60248201527f576973652074616720646f6573206e6f74206d6174636820726567697374657260448201526a656420776973652074616760a81b6064820152608401610765565b60028101546005116116475760405162461bcd60e51b815260206004820152601e60248201527f4d6178696d756d206465706f73697420616d6f756e74207265616368656400006044820152606401610765565b6006548510156116b85760405162461bcd60e51b815260206004820152603660248201527f4465706f73697420616d6f756e74206d757374206265206772656174657220746044820152751a185b881b5a5b8819195c1bdcda5d08185b5bdd5b9d60521b6064820152608401610765565b600084116117165760405162461bcd60e51b815260206004820152602560248201527f5265636569766520616d6f756e74206d75737420626520677265617465722074604482015264068616e20360dc1b6064820152608401610765565b60008461172b670de0b6b3a764000088614185565b61173591906141b2565b600c8054919250600091908261174a836140e2565b9091555060028401805460018101825560009182526020918290200182905560408051610120810182523381528151601f8e018490048402810184019092528c8252929350828201918d908d908190840183828082843760009201829052509385525050506001600160a01b03881660208084019190915260408084018c9052606084018d9052608084018c905260a0840183905260c084018790528051838152918201905260e090920191905090526000828152600460209081526040909120825181546001600160a01b0319166001600160a01b0390911617815590820151600182019061183a908261420c565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e0820151600782015561010082015180516118af9160088401916020909101906138f9565b50506040516323b872dd60e01b8152336004820152306024820152604481018990527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691506323b872dd906064016020604051808303816000875af1158015611925573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611949919061403a565b50835160408051898152602081018590528a929184917f94c4b6f8843ea372709c89bc4a9ed85ef74ab10a68713ffdddc31716a76a6c95910160405180910390a450505050505050505050565b60008060006119a6868686612d47565b6040805160a08101825284546001600160a01b0390811682526001860154166020820152600285015491810191909152600384015460608201526004909301546080840152919450925090506119fc8282613160565b8260600151826006016000828254611a149190614085565b9091555050600154835160405163e0b490f760e01b81526001600160a01b039182166004820152429260039260009291169063e0b490f790602401602060405180830381865afa158015611a6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a909190614021565b815260200190815260200160002060010181905550611ab38360400151836132a9565b611abd818461341f565b505050505050565b611acd612a79565b66b1a2bc2ec50000811115611b2f5760405162461bcd60e51b815260206004820152602260248201527f4665652063616e6e6f742062652067726561746572207468616e206d61782066604482015261656560f01b6064820152608401610765565b600a8190556040518181527f44f48e1b871e6db1e909a7b253b054b7150a0b4ddf4d59b159c827d82e72567090602001610679565b6000818152600560209081526040808320815160a08101835281546001600160a01b03908116825260018301548116828601526002830154828501819052600384015460608401526004938401546080840152865291909352922081519192909116611c0a5760405162461bcd60e51b8152602060048201526015602482015274125b9d195b9d08191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606401610765565b80546001600160a01b03163314611c635760405162461bcd60e51b815260206004820152601c60248201527f43616c6c6572206d75737420626520746865206465706f7369746f72000000006044820152606401610765565b611c6d8184613160565b8160600151816006016000828254611c859190614085565b9091555050600154825160405163e0b490f760e01b81526001600160a01b039182166004820152429260039260009291169063e0b490f790602401602060405180830381865afa158015611cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d019190614021565b815260200190815260200160002060010181905550611d248260400151826132a9565b611d2e838361341f565b505050565b6000805b8251811015611e94576000838281518110611d5457611d54614098565b6020908102919091018101516000818152600490925260409091208054919250906001600160a01b03163314611dcc5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206d75737420626520746865206465706f7369746f72000000006044820152606401610765565b600080611dd884612b3e565b91509150611de68383612ce5565b808360050154611df69190614072565b611e009087614072565b955080836006016000828254611e169190614085565b9091555050825460058401546001600160a01b039091169085907fae1f357660ab777dcfd38c0ab6357834684ec26289ecfa07ec65dbf6c3c6431290611e5d908590614072565b60405190815260200160405180910390a360006005840155611e7f84846132a9565b5050505080611e8d906140e2565b9050611d37565b5060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015611f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2e919061403a565b611f2e612a79565b611f3860006135fd565b565b606081516001600160401b03811115611f5557611f55613d9e565b604051908082528060200260200182016040528015611f8e57816020015b611f7b6138cd565b815260200190600190039081611f735790505b50905060005b825181101561221c576000838281518110611fb157611fb1614098565b60209081029190910181015160008181526004835260408082208151610120810190925280546001600160a01b031682526001810180549496509294919390929184019190611fff906140ae565b80601f016020809104026020016040519081016040528092919081815260200182805461202b906140ae565b80156120785780601f1061204d57610100808354040283529160200191612078565b820191906000526020600020905b81548152906001019060200180831161205b57829003601f168201915b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820180548060200260200160405190810160405280929190818152602001828054801561213157602002820191906000526020600020905b81548152602001906001019080831161211d575b5050505050815250509050600061214783612b3e565b604080516080810182528681526001548651925163e0b490f760e01b81526001600160a01b039384166004820152939550909350602084019291169063e0b490f790602401602060405180830381865afa1580156121a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121cd9190614021565b8152602001838152602001828460a001516121e89190614072565b8152508585815181106121fd576121fd614098565b602002602001018190525050505080612215906140e2565b9050611f94565b50919050565b61222a612a79565b806000036122845760405162461bcd60e51b815260206004820152602160248201527f4d6178206f6e2072616d7020616d6f756e742063616e6e6f74206265207a65726044820152606f60f81b6064820152608401610765565b60078190556040518181527fcab6b49ca21dd111cf4a55d507bbe89dd12d69216e28247060d4b2163ca41b3990602001610679565b6122c1613944565b6000828152600460209081526040918290208251610120810190935280546001600160a01b0316835260018101805491928401916122fe906140ae565b80601f016020809104026020016040519081016040528092919081815260200182805461232a906140ae565b80156123775780601f1061234c57610100808354040283529160200191612377565b820191906000526020600020905b81548152906001019060200180831161235a57829003601f168201915b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820180548060200260200160405190810160405280929190818152602001828054801561243057602002820191906000526020600020905b81548152602001906001019080831161241c575b5050505050815250509050919050565b600460205260009081526040902080546001820180546001600160a01b03909216929161246c906140ae565b80601f0160208091040260200160405190810160405280929190818152602001828054612498906140ae565b80156124e55780601f106124ba576101008083540402835291602001916124e5565b820191906000526020600020905b8154815290600101906020018083116124c857829003601f168201915b5050506002840154600385015460048601546005870154600688015460079098015496976001600160a01b0390941696929550909350919088565b600061252b82610684565b92915050565b612539612a79565b6001600160a01b03811661259b5760405162461bcd60e51b8152602060048201526024808201527f46656520726563697069656e742063616e6e6f74206265207a65726f206164646044820152637265737360e01b6064820152608401610765565b600b80546001600160a01b0319166001600160a01b0383169081179091556040519081527f594ad6ee98bfc0c73e6d15fd4e762502f359e05d26907b7fa1ff82eb5e99f6e490602001610679565b6000818152600560209081526040808320815160a08101835281546001600160a01b039081168252600183015416938101939093526002810154918301919091526003810154606083015260040154608082018190529091036126865760405162461bcd60e51b8152602060048201526015602482015274125b9d195b9d08191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606401610765565b60015460405163e0b490f760e01b81523360048201526001600160a01b039091169063e0b490f790602401602060405180830381865afa1580156126ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126f29190614021565b600154825160405163e0b490f760e01b81526001600160a01b03918216600482015291169063e0b490f790602401602060405180830381865afa15801561273d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127619190614021565b146127ae5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206d75737420626520746865206f6e2d72616d706572000000006044820152606401610765565b60408082015160009081526004602052206127c98184613160565b81606001518160050160008282546127e19190614072565b909155505060608201516006820180546000906127ff908490614085565b9091555050505050565b60606000826001600160401b0381111561282557612825613d9e565b60405190808252806020026020018201604052801561289f57816020015b61288c60408051606080820183526000808352835160a0810185528181526020818101839052948101829052918201819052608082015290918201908152600060209091015290565b8152602001906001900390816128435790505b50905060005b838110156129f85760008585838181106128c1576128c1614098565b60209081029290920135600081815260058452604090819020815160a08101835281546001600160a01b0390811682526001830154169581019590955260028101548583015260038101546060808701919091526004909101546080860152815190810190915290935090508088888681811061294057612940614098565b60209081029290920135835250810183905260015483516040805163e0b490f760e01b81526001600160a01b03928316600482015293019291169063e0b490f790602401602060405180830381865afa1580156129a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c59190614021565b8152508484815181106129da576129da614098565b60200260200101819052505050806129f1906140e2565b90506128a5565b509392505050565b612a08612a79565b6001600160a01b038116612a6d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610765565b612a76816135fd565b50565b6000546001600160a01b03163314611f385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610765565b6040805160208101849052908101829052426060820152600090819060800160408051601f1981840301815291905280516020909101209050612b367f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001826142cb565b949350505050565b60008181526004602090815260408083206008018054825181850281018501909352808352606094938493929190830182828015612b9b57602002820191906000526020600020905b815481526020019060010190808311612b87575b5050505050905080516001600160401b03811115612bbb57612bbb613d9e565b604051908082528060200260200182016040528015612be4578160200160208202803683370190505b50925060005b8151811015612cde57600060056000848481518110612c0b57612c0b614098565b6020908102919091018101518252818101929092526040908101600020815160a08101835281546001600160a01b039081168252600183015416938101939093526002810154918301919091526003810154606083015260040154608082018190526009549192504291612c7e91614072565b1015612ccd57828281518110612c9657612c96614098565b6020026020010151858381518110612cb057612cb0614098565b60209081029190910101526060810151612cca9085614072565b93505b50612cd7816140e2565b9050612bea565b5050915091565b60005b8151811015611d2e576000801b828281518110612d0757612d07614098565b602002602001015114612d3757612d3783838381518110612d2a57612d2a614098565b6020026020010151613160565b612d40816140e2565b9050612ce8565b610120830135600081815260056020526040812080549092906001600160a01b03163314612db75760405162461bcd60e51b815260206004820152601c60248201527f43616c6c6572206d75737420626520746865206f6e2d72616d706572000000006044820152606401610765565b60028084015460009081526004602052604080822092548151808301909252929450909182918291829182916001600160a01b03169063f20333c19080612dfd8f61434e565b81526020018d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505091525060028a01546040516001600160e01b031960e085901b168152612e6a92916001600160a01b0316906004016144ce565b60a0604051808303816000875af1158015612e89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ead9190614626565b9450945094509450945086600401548114612f005760405162461bcd60e51b815260206004820152601360248201527215dc9bdb99c818dd5c9c995b98de481cd95b9d606a1b6044820152606401610765565b8388600401541115612f5f5760405162461bcd60e51b815260206004820152602260248201527f496e74656e7420776173206e6f742063726561746564206265666f72652073656044820152611b9960f21b6064820152608401610765565b6001548754604051630f6a21fd60e31b81526001600160a01b03918216600482015285929190911690637b510fe890602401606060405180830381865afa158015612fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd291906140fb565b60200151146130235760405162461bcd60e51b815260206004820152601b60248201527f4f666672616d70657220696420646f6573206e6f74206d6174636800000000006044820152606401610765565b600154885460405163e0b490f760e01b81526001600160a01b0391821660048201528492919091169063e0b490f790602401602060405180830381865afa158015613072573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130969190614021565b146130e35760405162461bcd60e51b815260206004820152601a60248201527f4f6e72616d70657220696420646f6573206e6f74206d617463680000000000006044820152606401610765565b8660070154670de0b6b3a764000089600301546131009190614185565b61310a91906141b2565b8510156131525760405162461bcd60e51b81526020600482015260166024820152750a0c2f2dacadce840eec2e640dcdee840cadcdeeaced60531b6044820152606401610765565b505050505093509350939050565b6000818152600560209081526040808320815160a08101835281546001600160a01b03908116808352600180850154831696840196909652600284015483860152600380850154606085015260049485015460808501529554945163e0b490f760e01b815293840152909492169063e0b490f790602401602060405180830381865afa1580156131f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132189190614021565b8152602080820192909252604090810160009081208190558481526005909252812080546001600160a01b031990811682556001820180549091169055600281018290556003810182905560040155613274600884018361364d565b604080820151905183907fe8a865b4bab023c399cbd1f2cdd0df2199beb6e5012a4bd2d7691cf7e4199d5a90600090a3505050565b6000816005015482600601546132bf9190614072565b905080600003611d2e57600154825460405163e0b490f760e01b81526001600160a01b039182166004820152613365928692600392600092919091169063e0b490f790602401602060405180830381865afa158015613322573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133469190614021565b815260200190815260200160002060020161377590919063ffffffff16565b8154604080518581526001600160a01b0390921660208301527f8ac07cc6e38c6222dd0309c80353c1962354bacf222b825d7401cc80e93ff3cc910160405180910390a1600083815260046020526040812080546001600160a01b0319168155906133d360018301826139a5565b6002820180546001600160a01b0319169055600060038301819055600483018190556005830181905560068301819055600783018190556134189060088401906139df565b5050505050565b6000600a546000146134eb57670de0b6b3a7640000600a5483606001516134469190614185565b61345091906141b2565b600b5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156134c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134e9919061403a565b505b60008183606001516134fd9190614085565b602084015160405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015613574573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613598919061403a565b50825160408085015160208087015183516001600160a01b03918216815291820186905292810186905291909216919086907ffa03438194e61c243c6bb5349f1e1dc674431b86f119b5e3b2b327bc43446bce9060600160405180910390a450505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806136a98480548060200260200160405190810160405280929190818152602001828054801561369e57602002820191906000526020600020905b81548152602001906001019080831161368a575b50505050508461381a565b91509150806136f25760405162461bcd60e51b8152602060048201526015602482015274313cba32b99999103737ba1034b71030b93930bc9760591b6044820152606401610765565b835460009061370390600190614085565b90508083146137485784818154811061371e5761371e614098565b906000526020600020015485848154811061373b5761373b614098565b6000918252602090912001555b8480548061375857613758614666565b600190038181906000526020600020016000905590555050505050565b6000806137d1848054806020026020016040519081016040528092919081815260200182805480156137c657602002820191906000526020600020905b8154815260200190600101908083116137b2575b50505050508461387d565b91509150806136f25760405162461bcd60e51b81526020600482015260156024820152743ab4b73a191a9b103737ba1034b71030b93930bc9760591b6044820152606401610765565b81516000908190815b8181101561386a578486828151811061383e5761383e614098565b602002602001015103613858579250600191506138769050565b80613862816140e2565b915050613823565b50600019600092509250505b9250929050565b81516000908190815b8181101561386a57848682815181106138a1576138a1614098565b6020026020010151036138bb579250600191506138769050565b806138c5816140e2565b915050613886565b60408051608081018252600080825260208201529081016138ec613944565b8152602001600081525090565b828054828255906000526020600020908101928215613934579160200282015b82811115613934578251825591602001919060010190613919565b506139409291506139f9565b5090565b60405180610120016040528060006001600160a01b031681526020016060815260200160006001600160a01b031681526020016000815260200160008019168152602001600081526020016000815260200160008152602001606081525090565b5080546139b1906140ae565b6000825580601f106139c1575050565b601f016020900490600052602060002090810190612a7691906139f9565b5080546000825590600052602060002090810190612a7691905b5b8082111561394057600081556001016139fa565b6001600160a01b0381168114612a7657600080fd5b600060208284031215613a3557600080fd5b8135613a4081613a0e565b9392505050565b600060208284031215613a5957600080fd5b5035919050565b600080600060608486031215613a7557600080fd5b83359250602084013591506040840135613a8e81613a0e565b809150509250925092565b60008060408385031215613aac57600080fd5b8235613ab781613a0e565b91506020830135613ac781613a0e565b809150509250929050565b6000815180845260005b81811015613af857602081850181015186830182015201613adc565b506000602082860101526020601f19601f83011685010191505092915050565b600081518084526020808501945080840160005b83811015613b4857815187529582019590820190600101613b2c565b509495945050505050565b80516001600160a01b0316825260006101206020830151816020860152613b7c82860182613ad2565b9150506040830151613b9960408601826001600160a01b03169052565b50606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e083015160e08501526101008084015185830382870152613be48382613b18565b9695505050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015613c6c57603f1989840301855281516080815185528882015189860152878201518189870152613c4b82870182613b53565b60609384015196909301959095525094870194925090860190600101613c15565b509098975050505050505050565b60008083601f840112613c8c57600080fd5b5081356001600160401b03811115613ca357600080fd5b60208301915083602082850101111561387657600080fd5b60008060008060008060a08789031215613cd457600080fd5b86356001600160401b03811115613cea57600080fd5b613cf689828a01613c7a565b9097509550506020870135935060408701359250606087013591506080870135613d1f81613a0e565b809150509295509295509295565b600080600060408486031215613d4257600080fd5b83356001600160401b0380821115613d5957600080fd5b908501906101408288031215613d6e57600080fd5b90935060208501359080821115613d8457600080fd5b50613d9186828701613c7a565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405161014081016001600160401b0381118282101715613dd757613dd7613d9e565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613e0557613e05613d9e565b604052919050565b60006020808385031215613e2057600080fd5b82356001600160401b0380821115613e3757600080fd5b818501915085601f830112613e4b57600080fd5b813581811115613e5d57613e5d613d9e565b8060051b9150613e6e848301613ddd565b8181529183018401918481019088841115613e8857600080fd5b938501935b83851015613ea657843582529385019390850190613e8d565b98975050505050505050565b602081526000613a406020830184613b53565b6001600160a01b03898116825261010060208301819052600091613eeb8483018c613ad2565b9916604084015250506060810195909552608085019390935260a084019190915260c083015260e09091015292915050565b60008060208385031215613f3057600080fd5b82356001600160401b0380821115613f4757600080fd5b818501915085601f830112613f5b57600080fd5b813581811115613f6a57600080fd5b8660208260051b8501011115613f7f57600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b82811015614014578151805185528681015180516001600160a01b039081168988015281890151168787015286810151606080880191909152810151608080880191909152015160a086015285015160c085015260e09093019290850190600101613fae565b5091979650505050505050565b60006020828403121561403357600080fd5b5051919050565b60006020828403121561404c57600080fd5b81518015158114613a4057600080fd5b634e487b7160e01b600052601160045260246000fd5b8082018082111561252b5761252b61405c565b8181038181111561252b5761252b61405c565b634e487b7160e01b600052603260045260246000fd5b600181811c908216806140c257607f821691505b60208210810361221c57634e487b7160e01b600052602260045260246000fd5b6000600182016140f4576140f461405c565b5060010190565b60006060828403121561410d57600080fd5b604051606081018181106001600160401b038211171561412f5761412f613d9e565b80604052508251815260208301516020820152604083015160408201528091505092915050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b808202811582820484141761252b5761252b61405c565b634e487b7160e01b600052601260045260246000fd5b6000826141c1576141c161419c565b500490565b601f821115611d2e57600081815260208120601f850160051c810160208610156141ed5750805b601f850160051c820191505b81811015611abd578281556001016141f9565b81516001600160401b0381111561422557614225613d9e565b6142398161423384546140ae565b846141c6565b602080601f83116001811461426e57600084156142565750858301515b600019600386901b1c1916600185901b178555611abd565b600085815260208120601f198616915b8281101561429d5788860151825594840194600190910190840161427e565b50858210156142bb5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000826142da576142da61419c565b500690565b600082601f8301126142f057600080fd5b81356001600160401b0381111561430957614309613d9e565b61431c601f8201601f1916602001613ddd565b81815284602083860101111561433157600080fd5b816020850160208301376000918101602001919091529392505050565b6000610140823603121561436157600080fd5b614369613db4565b82356001600160401b038082111561438057600080fd5b61438c368387016142df565b835260208501359150808211156143a257600080fd5b6143ae368387016142df565b602084015260408501359150808211156143c757600080fd5b6143d3368387016142df565b604084015260608501359150808211156143ec57600080fd5b6143f8368387016142df565b6060840152608085013591508082111561441157600080fd5b61441d368387016142df565b608084015260a085013591508082111561443657600080fd5b614442368387016142df565b60a084015260c085013591508082111561445b57600080fd5b614467368387016142df565b60c084015260e085013591508082111561448057600080fd5b61448c368387016142df565b60e0840152610100915081850135818111156144a757600080fd5b6144b3368288016142df565b92840192909252505061012092830135928101929092525090565b604081526000835160408084015280516101408060808601526144f56101c0860183613ad2565b91506020830151607f19808785030160a08801526145138483613ad2565b935060408501519150808785030160c08801526145308483613ad2565b935060608501519150808785030160e088015261454d8483613ad2565b93506080850151915061010081888603018189015261456c8584613ad2565b945060a086015192506101208289870301818a015261458b8685613ad2565b955060c087015193508289870301858a01526145a78685613ad2565b955060e0870151945082898703016101608a01526145c58686613ad2565b955081870151945082898703016101808a01526145e28686613ad2565b9601516101a0890152505050506020860151848303603f1901606086015291905061460d8183613ad2565b92505050613a4060208301846001600160a01b03169052565b600080600080600060a0868803121561463e57600080fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220e73047b166610e8f47090fb36d9adea76ccf223d5d22f65c8ecedd7f9ee46b8b64736f6c63430008120033", + "solcInputHash": "0de631e329f560f49e3d6a21d19a30cc", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"contract IERC20\",\"name\":\"_usdc\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minDepositAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxOnRampAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_intentExpirationPeriod\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_onRampCooldownPeriod\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_sustainabilityFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sustainabilityFeeRecipient\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"}],\"name\":\"DepositClosed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"offRampId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"currencyId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"conversionRate\",\"type\":\"uint256\"}],\"name\":\"DepositReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DepositWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"intentExpirationPeriod\",\"type\":\"uint256\"}],\"name\":\"IntentExpirationPeriodSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"intentHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"onRamper\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"}],\"name\":\"IntentFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"intentHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"}],\"name\":\"IntentPruned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"intentHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"accountId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"IntentSignaled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxOnRampAmount\",\"type\":\"uint256\"}],\"name\":\"MaxOnRampAmountSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"minDepositAmount\",\"type\":\"uint256\"}],\"name\":\"MinDepositAmountSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sendProcessor\",\"type\":\"address\"}],\"name\":\"NewSendProcessorSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"onRampCooldownPeriod\",\"type\":\"uint256\"}],\"name\":\"OnRampCooldownPeriodSet\",\"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\":false,\"internalType\":\"address\",\"name\":\"feeRecipient\",\"type\":\"address\"}],\"name\":\"SustainabilityFeeRecipientUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"name\":\"SustainabilityFeeUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accountRegistry\",\"outputs\":[{\"internalType\":\"contract IWiseAccountRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_intentHash\",\"type\":\"bytes32\"}],\"name\":\"cancelIntent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositCounter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"wiseTag\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"verifierSigningKey\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"depositAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"receiveCurrencyId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"remainingDeposits\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outstandingIntentAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"conversionRate\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getAccountDeposits\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"depositorId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"wiseTag\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"verifierSigningKey\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"depositAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"receiveCurrencyId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"remainingDeposits\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outstandingIntentAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"conversionRate\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"intentHashes\",\"type\":\"bytes32[]\"}],\"internalType\":\"struct WiseRamp.Deposit\",\"name\":\"deposit\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"availableLiquidity\",\"type\":\"uint256\"}],\"internalType\":\"struct WiseRamp.DepositWithAvailableLiquidity[]\",\"name\":\"accountDeposits\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_depositId\",\"type\":\"uint256\"}],\"name\":\"getDeposit\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"wiseTag\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"verifierSigningKey\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"depositAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"receiveCurrencyId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"remainingDeposits\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outstandingIntentAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"conversionRate\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"intentHashes\",\"type\":\"bytes32[]\"}],\"internalType\":\"struct WiseRamp.Deposit\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_depositIds\",\"type\":\"uint256[]\"}],\"name\":\"getDepositFromIds\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"depositorId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"depositor\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"wiseTag\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"verifierSigningKey\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"depositAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"receiveCurrencyId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"remainingDeposits\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outstandingIntentAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"conversionRate\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"intentHashes\",\"type\":\"bytes32[]\"}],\"internalType\":\"struct WiseRamp.Deposit\",\"name\":\"deposit\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"availableLiquidity\",\"type\":\"uint256\"}],\"internalType\":\"struct WiseRamp.DepositWithAvailableLiquidity[]\",\"name\":\"depositArray\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getIdCurrentIntentHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getIdCurrentIntentHashAsUint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"_intentHashes\",\"type\":\"bytes32[]\"}],\"name\":\"getIntentsWithOnRamperId\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"intentHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"onRamper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"intentTimestamp\",\"type\":\"uint256\"}],\"internalType\":\"struct WiseRamp.Intent\",\"name\":\"intent\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"onRamperId\",\"type\":\"bytes32\"}],\"internalType\":\"struct WiseRamp.IntentWithOnRamperId[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getLastOnRampTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWiseAccountRegistry\",\"name\":\"_accountRegistry\",\"type\":\"address\"},{\"internalType\":\"contract IWiseSendProcessor\",\"name\":\"_sendProcessor\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"intentExpirationPeriod\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"intents\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"onRamper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"intentTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxOnRampAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minDepositAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_wiseTag\",\"type\":\"string\"},{\"internalType\":\"bytes32\",\"name\":\"_receiveCurrencyId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_depositAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_receiveAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"}],\"name\":\"offRamp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"transferId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"senderId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"recipientId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"amount\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"currencyId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"status\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"timestamp\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"intentHash\",\"type\":\"uint256\"}],\"internalType\":\"struct IWiseSendProcessor.SendData\",\"name\":\"_sendData\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"_verifierSignature\",\"type\":\"bytes\"}],\"name\":\"onRamp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"onRampCooldownPeriod\",\"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\":\"bytes32\",\"name\":\"_intentHash\",\"type\":\"bytes32\"}],\"name\":\"releaseFundsToOnramper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sendProcessor\",\"outputs\":[{\"internalType\":\"contract IWiseSendProcessor\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_intentExpirationPeriod\",\"type\":\"uint256\"}],\"name\":\"setIntentExpirationPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxOnRampAmount\",\"type\":\"uint256\"}],\"name\":\"setMaxOnRampAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minDepositAmount\",\"type\":\"uint256\"}],\"name\":\"setMinDepositAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_onRampCooldownPeriod\",\"type\":\"uint256\"}],\"name\":\"setOnRampCooldownPeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IWiseSendProcessor\",\"name\":\"_sendProcessor\",\"type\":\"address\"}],\"name\":\"setSendProcessor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"setSustainabilityFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_feeRecipient\",\"type\":\"address\"}],\"name\":\"setSustainabilityFeeRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_depositId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"signalIntent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sustainabilityFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sustainabilityFeeRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"usdc\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_depositIds\",\"type\":\"uint256[]\"}],\"name\":\"withdrawDeposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelIntent(bytes32)\":{\"params\":{\"_intentHash\":\"Hash of intent being cancelled\"}},\"initialize(address,address)\":{\"params\":{\"_accountRegistry\":\"Account Registry contract for Wise\",\"_sendProcessor\":\"Send processor address\"}},\"offRamp(string,bytes32,uint256,uint256,address)\":{\"params\":{\"_depositAmount\":\"The amount of USDC to off-ramp\",\"_receiveAmount\":\"The amount of USD to receive\",\"_receiveCurrencyId\":\"Id of the currency to be received off-chain\",\"_verifierSigningKey\":\"Public key of the verifier depositor wants to sign the TLS proof\",\"_wiseTag\":\"Depositor's Wise tag to receive payments\"}},\"onRamp((string,string,string,string,string,string,string,string,string,uint256),bytes)\":{\"params\":{\"_sendData\":\"Struct containing unredacted data from API call to Wise\",\"_verifierSignature\":\"Signature by verifier of the unredacted data\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"releaseFundsToOnramper(bytes32)\":{\"params\":{\"_intentHash\":\"Hash of intent to resolve by releasing the funds\"}},\"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.\"},\"setIntentExpirationPeriod(uint256)\":{\"params\":{\"_intentExpirationPeriod\":\"New intent expiration period\"}},\"setMaxOnRampAmount(uint256)\":{\"params\":{\"_maxOnRampAmount\":\"The new max on ramp amount\"}},\"setMinDepositAmount(uint256)\":{\"params\":{\"_minDepositAmount\":\"The new minimum deposit amount\"}},\"setOnRampCooldownPeriod(uint256)\":{\"params\":{\"_onRampCooldownPeriod\":\"New on-ramp cooldown period\"}},\"setSendProcessor(address)\":{\"params\":{\"_sendProcessor\":\"New send proccesor address\"}},\"setSustainabilityFee(uint256)\":{\"params\":{\"_fee\":\"The new sustainability fee in precise units (10**18, ie 10% = 1e17)\"}},\"setSustainabilityFeeRecipient(address)\":{\"params\":{\"_feeRecipient\":\"The new fee recipient address\"}},\"signalIntent(uint256,uint256,address)\":{\"params\":{\"_amount\":\"The amount of USDC the user wants to on-ramp\",\"_depositId\":\"The ID of the deposit the on-ramper intends to use for \",\"_to\":\"Address to forward funds to (can be same as onRamper)\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"withdrawDeposit(uint256[])\":{\"params\":{\"_depositIds\":\"Array of depositIds the depositor is attempting to withdraw\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelIntent(bytes32)\":{\"notice\":\"Only callable by the originator of the intent. Cancels an outstanding intent thus allowing user to signal a new intent. Deposit state is updated to reflect the cancelled intent.\"},\"initialize(address,address)\":{\"notice\":\"Initialize Ramp with the addresses of the Processors\"},\"offRamp(string,bytes32,uint256,uint256,address)\":{\"notice\":\"Generates a deposit entry for off-rampers that can then be fulfilled by an on-ramper. This function will not add to previous deposits. Every deposit has it's own unique identifier. User must approve the contract to transfer the deposit amount of USDC.\"},\"onRamp((string,string,string,string,string,string,string,string,string,uint256),bytes)\":{\"notice\":\"Anyone can submit an on-ramp transaction, even if caller isn't on-ramper. Upon submission the proof is validated, intent is removed, and deposit state is updated. USDC is transferred to the on-ramper.\"},\"releaseFundsToOnramper(bytes32)\":{\"notice\":\"Allows off-ramper to release funds to the on-ramper in case of a failed on-ramp or because of some other arrangement between the two parties. Upon submission we check to make sure the msg.sender is the depositor, the intent is removed, and deposit state is updated. USDC is transferred to the on-ramper.\"},\"setIntentExpirationPeriod(uint256)\":{\"notice\":\"GOVERNANCE ONLY: Updates the intent expiration period, after this period elapses an intent can be pruned to prevent locking up a depositor's funds.\"},\"setMaxOnRampAmount(uint256)\":{\"notice\":\"GOVERNANCE ONLY: Updates the max amount allowed to be on-ramped in each transaction. To on-ramp more than this amount a user must make multiple transactions.\"},\"setMinDepositAmount(uint256)\":{\"notice\":\"GOVERNANCE ONLY: Updates the minimum deposit amount a user can specify for off-ramping.\"},\"setOnRampCooldownPeriod(uint256)\":{\"notice\":\"GOVERNANCE ONLY: Updates the on-ramp cooldown period, once an on-ramp transaction is completed the user must wait this amount of time before they can signalIntent to on-ramp again.\"},\"setSendProcessor(address)\":{\"notice\":\"GOVERNANCE ONLY: Updates the send processor address used for validating and interpreting zk proofs.\"},\"setSustainabilityFee(uint256)\":{\"notice\":\"GOVERNANCE ONLY: Updates the sustainability fee. This fee is charged to on-rampers upon a successful on-ramp.\"},\"setSustainabilityFeeRecipient(address)\":{\"notice\":\"GOVERNANCE ONLY: Updates the recepient of sustainability fees.\"},\"signalIntent(uint256,uint256,address)\":{\"notice\":\"Signals intent to pay the depositor defined in the _depositId the _amount * deposit conversionRate off-chain in order to unlock _amount of funds on-chain. Each user can only have one outstanding intent at a time regardless of address (tracked using accountId). Caller must not be on the depositor's deny list. If there are prunable intents then they will be deleted from the deposit to be able to maintain state hygiene.\"},\"withdrawDeposit(uint256[])\":{\"notice\":\"Caller must be the depositor for each depositId in the array, if not whole function fails. Depositor is returned all remaining deposits and any outstanding intents that are expired. If an intent is not expired then those funds will not be returned. Deposit will be deleted as long as there are no more outstanding intents.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ramps/wise/WiseRamp.sol\":\"WiseRamp\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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/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/external/Bytes32ArrayUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.17;\\n\\n/**\\n * @title Bytes32ArrayUtils\\n * @author ZKP2P\\n *\\n * Fork of Set Protocol's AddressArrayUtils library adapted for usage with bytes32 arrays.\\n */\\nlibrary Bytes32ArrayUtils {\\n\\n uint256 constant internal MAX_INT = 2**256 - 1;\\n\\n /**\\n * Finds the index of the first occurrence of the given element.\\n * @param A The input array to search\\n * @param a The value to find\\n * @return Returns (index and isIn) for the first occurrence starting from index 0\\n */\\n function indexOf(bytes32[] memory A, bytes32 a) internal pure returns (uint256, bool) {\\n uint256 length = A.length;\\n for (uint256 i = 0; i < length; i++) {\\n if (A[i] == a) {\\n return (i, true);\\n }\\n }\\n return (MAX_INT, false);\\n }\\n\\n /**\\n * Returns true if the value is present in the list. Uses indexOf internally.\\n * @param A The input array to search\\n * @param a The value to find\\n * @return Returns isIn for the first occurrence starting from index 0\\n */\\n function contains(bytes32[] memory A, bytes32 a) internal pure returns (bool) {\\n (, bool isIn) = indexOf(A, a);\\n return isIn;\\n }\\n\\n /**\\n * Returns true if there are 2 elements that are the same in an array\\n * @param A The input array to search\\n * @return Returns boolean for the first occurrence of a duplicate\\n */\\n function hasDuplicate(bytes32[] memory A) internal pure returns(bool) {\\n require(A.length > 0, \\\"A is empty\\\");\\n\\n for (uint256 i = 0; i < A.length - 1; i++) {\\n bytes32 current = A[i];\\n for (uint256 j = i + 1; j < A.length; j++) {\\n if (current == A[j]) {\\n return true;\\n }\\n }\\n }\\n return false;\\n }\\n\\n /**\\n * @param A The input array to search\\n * @param a The bytes32 to remove\\n * @return Returns the array with the object removed.\\n */\\n function remove(bytes32[] memory A, bytes32 a)\\n internal\\n pure\\n returns (bytes32[] memory)\\n {\\n (uint256 index, bool isIn) = indexOf(A, a);\\n if (!isIn) {\\n revert(\\\"bytes32 not in array.\\\");\\n } else {\\n (bytes32[] memory _A,) = pop(A, index);\\n return _A;\\n }\\n }\\n\\n /**\\n * @param A The input array to search\\n * @param a The bytes32 to remove\\n */\\n function removeStorage(bytes32[] storage A, bytes32 a)\\n internal\\n {\\n (uint256 index, bool isIn) = indexOf(A, a);\\n if (!isIn) {\\n revert(\\\"bytes32 not in array.\\\");\\n } else {\\n uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here\\n if (index != lastIndex) { A[index] = A[lastIndex]; }\\n A.pop();\\n }\\n }\\n\\n /**\\n * Removes specified index from array\\n * @param A The input array to search\\n * @param index The index to remove\\n * @return Returns the new array and the removed entry\\n */\\n function pop(bytes32[] memory A, uint256 index)\\n internal\\n pure\\n returns (bytes32[] memory, bytes32)\\n {\\n uint256 length = A.length;\\n require(index < A.length, \\\"Index must be < A length\\\");\\n bytes32[] memory newBytes = new bytes32[](length - 1);\\n for (uint256 i = 0; i < index; i++) {\\n newBytes[i] = A[i];\\n }\\n for (uint256 j = index + 1; j < length; j++) {\\n newBytes[j - 1] = A[j];\\n }\\n return (newBytes, A[index]);\\n }\\n}\\n\",\"keccak256\":\"0x14d572deda126ff812eb5ab0eed33120e13cc568fd611a4a6bff652f3e8440a8\",\"license\":\"MIT\"},\"contracts/external/Uint256ArrayUtils.sol\":{\"content\":\"/*\\n Copyright 2020 Set Labs Inc.\\n\\n Licensed under the Apache License, Version 2.0 (the \\\"License\\\");\\n you may not use this file except in compliance with the License.\\n You may obtain a copy of the License at\\n\\n http://www.apache.org/licenses/LICENSE-2.0\\n\\n Unless required by applicable law or agreed to in writing, software\\n distributed under the License is distributed on an \\\"AS IS\\\" BASIS,\\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\\n See the License for the specific language governing permissions and\\n limitations under the License.\\n\\n SPDX-License-Identifier: Apache-2.0\\n*/\\n\\npragma solidity ^0.8.18;\\n\\n/**\\n * @title Uint256ArrayUtils\\n * @author Set Protocol\\n *\\n * Utility functions to handle Uint256 Arrays\\n */\\nlibrary Uint256ArrayUtils {\\n\\n uint256 constant internal MAX_INT = 2**256 - 1;\\n\\n /**\\n * Finds the index of the first occurrence of the given element.\\n * @param A The input array to search\\n * @param a The value to find\\n * @return Returns (index and isIn) for the first occurrence starting from index 0\\n */\\n function indexOf(uint256[] memory A, uint256 a) internal pure returns (uint256, bool) {\\n uint256 length = A.length;\\n for (uint256 i = 0; i < length; i++) {\\n if (A[i] == a) {\\n return (i, true);\\n }\\n }\\n return (MAX_INT, false);\\n }\\n\\n /**\\n * Returns the combination of the two arrays\\n * @param A The first array\\n * @param B The second array\\n * @return Returns A extended by B\\n */\\n function extend(uint256[] memory A, uint256[] memory B) internal pure returns (uint256[] memory) {\\n uint256 aLength = A.length;\\n uint256 bLength = B.length;\\n uint256[] memory newUints = new uint256[](aLength + bLength);\\n for (uint256 i = 0; i < aLength; i++) {\\n newUints[i] = A[i];\\n }\\n for (uint256 j = 0; j < bLength; j++) {\\n newUints[aLength + j] = B[j];\\n }\\n return newUints;\\n }\\n\\n /**\\n * @param A The input array to search\\n * @param a The bytes32 to remove\\n */\\n function removeStorage(uint256[] storage A, uint256 a)\\n internal\\n {\\n (uint256 index, bool isIn) = indexOf(A, a);\\n if (!isIn) {\\n revert(\\\"uint256 not in array.\\\");\\n } else {\\n uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here\\n if (index != lastIndex) { A[index] = A[lastIndex]; }\\n A.pop();\\n }\\n }\\n}\\n\",\"keccak256\":\"0x102021415f8444ff563fc6d0082f39296f47c09ce73fb4cd642e700ac489eefe\",\"license\":\"Apache-2.0\"},\"contracts/ramps/wise/WiseRamp.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { IERC20 } from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport { Bytes32ArrayUtils } from \\\"../../external/Bytes32ArrayUtils.sol\\\";\\nimport { Uint256ArrayUtils } from \\\"../../external/Uint256ArrayUtils.sol\\\";\\n\\nimport { IWiseAccountRegistry } from \\\"./interfaces/IWiseAccountRegistry.sol\\\";\\nimport { IWiseSendProcessor } from \\\"./interfaces/IWiseSendProcessor.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract WiseRamp is Ownable {\\n\\n using Bytes32ArrayUtils for bytes32[];\\n using Uint256ArrayUtils for uint256[];\\n\\n /* ============ Events ============ */\\n event DepositReceived(\\n uint256 indexed depositId,\\n bytes32 indexed offRampId,\\n bytes32 indexed currencyId,\\n uint256 amount,\\n uint256 conversionRate\\n );\\n event IntentSignaled(\\n bytes32 indexed intentHash,\\n uint256 indexed depositId,\\n bytes32 indexed accountId,\\n address to,\\n uint256 amount,\\n uint256 timestamp\\n );\\n\\n event IntentPruned(\\n bytes32 indexed intentHash,\\n uint256 indexed depositId\\n );\\n event IntentFulfilled(\\n bytes32 indexed intentHash,\\n uint256 indexed depositId,\\n address indexed onRamper,\\n address to,\\n uint256 amount,\\n uint256 feeAmount\\n );\\n event DepositWithdrawn(\\n uint256 indexed depositId,\\n address indexed depositor,\\n uint256 amount\\n );\\n\\n event DepositClosed(uint256 depositId, address depositor);\\n event MinDepositAmountSet(uint256 minDepositAmount);\\n event MaxOnRampAmountSet(uint256 maxOnRampAmount);\\n event IntentExpirationPeriodSet(uint256 intentExpirationPeriod);\\n event OnRampCooldownPeriodSet(uint256 onRampCooldownPeriod);\\n event SustainabilityFeeUpdated(uint256 fee);\\n event SustainabilityFeeRecipientUpdated(address feeRecipient);\\n event NewSendProcessorSet(address sendProcessor);\\n\\n /* ============ Structs ============ */\\n\\n struct Deposit {\\n address depositor;\\n string wiseTag;\\n address verifierSigningKey; // Public key of the verifier depositor wants to sign the TLS proof\\n uint256 depositAmount; // Amount of USDC deposited\\n bytes32 receiveCurrencyId; // Id of the currency to be received off-chain (bytes32(Wise currency code))\\n uint256 remainingDeposits; // Amount of remaining deposited liquidity\\n uint256 outstandingIntentAmount; // Amount of outstanding intents (may include expired intents)\\n uint256 conversionRate; // Conversion required by off-ramper between USDC/USD\\n bytes32[] intentHashes; // Array of hashes of all open intents (may include some expired if not pruned)\\n }\\n\\n struct DepositWithAvailableLiquidity {\\n uint256 depositId; // ID of the deposit\\n bytes32 depositorId; // Depositor's offRampId \\n Deposit deposit; // Deposit struct\\n uint256 availableLiquidity; // Amount of liquidity available to signal intents (net of expired intents)\\n }\\n\\n struct Intent {\\n address onRamper; // On-ramper's address\\n address to; // Address to forward funds to (can be same as onRamper)\\n uint256 deposit; // ID of the deposit the intent is signaling on\\n uint256 amount; // Amount of USDC the on-ramper signals intent for on-chain\\n uint256 intentTimestamp; // Timestamp of when the intent was signaled\\n }\\n\\n struct IntentWithOnRamperId {\\n bytes32 intentHash; // Intent hash\\n Intent intent; // Intent struct\\n bytes32 onRamperId; // onRamper's onRamperId\\n }\\n\\n // A Global Account is defined as an account represented by one accountId. This is used to enforce limitations on actions across\\n // all Ethereum addresses that are associated with that accountId. In this case we use it to enforce a cooldown period between on ramps,\\n // restrict each Wise account to one outstanding intent at a time, and to enforce deny lists.\\n struct GlobalAccountInfo {\\n bytes32 currentIntentHash; // Hash of the current open intent (if exists)\\n uint256 lastOnrampTimestamp; // Timestamp of the last on-ramp transaction used to check if cooldown period elapsed\\n uint256[] deposits; // Array of open account deposits\\n }\\n\\n /* ============ Modifiers ============ */\\n modifier onlyRegisteredUser() {\\n require(accountRegistry.isRegisteredUser(msg.sender), \\\"Caller must be registered user\\\");\\n _;\\n }\\n\\n /* ============ Constants ============ */\\n uint256 internal constant PRECISE_UNIT = 1e18;\\n uint256 internal constant MAX_DEPOSITS = 5; // An account can only have max 5 different deposit parameterizations to prevent locking funds\\n uint256 constant CIRCOM_PRIME_FIELD = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\\n uint256 constant MAX_SUSTAINABILITY_FEE = 5e16; // 5% max sustainability fee\\n \\n /* ============ State Variables ============ */\\n IERC20 public immutable usdc; // USDC token contract\\n IWiseAccountRegistry public accountRegistry; // Account Registry contract for Wise\\n IWiseSendProcessor public sendProcessor; // Address of send processor contract\\n\\n bool public isInitialized; // Indicates if contract has been initialized\\n\\n mapping(bytes32 => GlobalAccountInfo) internal globalAccount; // Mapping of onRamp ID to information used to enforce actions across Ethereum accounts\\n mapping(uint256 => Deposit) public deposits; // Mapping of depositIds to deposit structs\\n mapping(bytes32 => Intent) public intents; // Mapping of intentHashes to intent structs\\n\\n uint256 public minDepositAmount; // Minimum amount of USDC that can be deposited\\n uint256 public maxOnRampAmount; // Maximum amount of USDC that can be on-ramped in a single transaction\\n uint256 public onRampCooldownPeriod; // Time period that must elapse between completing an on-ramp and signaling a new intent\\n uint256 public intentExpirationPeriod; // Time period after which an intent can be pruned from the system\\n uint256 public sustainabilityFee; // Fee charged to on-rampers in preciseUnits (1e16 = 1%)\\n address public sustainabilityFeeRecipient; // Address that receives the sustainability fee\\n\\n uint256 public depositCounter; // Counter for depositIds\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _owner,\\n IERC20 _usdc,\\n uint256 _minDepositAmount,\\n uint256 _maxOnRampAmount,\\n uint256 _intentExpirationPeriod,\\n uint256 _onRampCooldownPeriod,\\n uint256 _sustainabilityFee,\\n address _sustainabilityFeeRecipient\\n )\\n Ownable()\\n {\\n usdc = _usdc;\\n minDepositAmount = _minDepositAmount;\\n maxOnRampAmount = _maxOnRampAmount;\\n intentExpirationPeriod = _intentExpirationPeriod;\\n onRampCooldownPeriod = _onRampCooldownPeriod;\\n sustainabilityFee = _sustainabilityFee;\\n sustainabilityFeeRecipient = _sustainabilityFeeRecipient;\\n\\n transferOwnership(_owner);\\n }\\n\\n /* ============ External Functions ============ */\\n\\n /**\\n * @notice Initialize Ramp with the addresses of the Processors\\n *\\n * @param _accountRegistry Account Registry contract for Wise\\n * @param _sendProcessor Send processor address\\n */\\n function initialize(\\n IWiseAccountRegistry _accountRegistry,\\n IWiseSendProcessor _sendProcessor\\n )\\n external\\n onlyOwner\\n {\\n require(!isInitialized, \\\"Already initialized\\\");\\n\\n accountRegistry = _accountRegistry;\\n sendProcessor = _sendProcessor;\\n\\n isInitialized = true;\\n }\\n\\n /**\\n * @notice Generates a deposit entry for off-rampers that can then be fulfilled by an on-ramper. This function will not add to\\n * previous deposits. Every deposit has it's own unique identifier. User must approve the contract to transfer the deposit amount\\n * of USDC.\\n *\\n * @param _wiseTag Depositor's Wise tag to receive payments\\n * @param _receiveCurrencyId Id of the currency to be received off-chain\\n * @param _depositAmount The amount of USDC to off-ramp\\n * @param _receiveAmount The amount of USD to receive\\n * @param _verifierSigningKey Public key of the verifier depositor wants to sign the TLS proof\\n */\\n function offRamp(\\n string calldata _wiseTag,\\n bytes32 _receiveCurrencyId,\\n uint256 _depositAmount,\\n uint256 _receiveAmount,\\n address _verifierSigningKey\\n )\\n external\\n onlyRegisteredUser\\n {\\n IWiseAccountRegistry.AccountInfo memory account = accountRegistry.getAccountInfo(msg.sender);\\n GlobalAccountInfo storage globalAccountInfo = globalAccount[account.accountId];\\n\\n require(account.offRampId != bytes32(0), \\\"Must be registered as off ramper\\\");\\n require(keccak256(abi.encode(_wiseTag)) == account.wiseTagHash, \\\"Wise tag does not match registered wise tag\\\");\\n require(globalAccountInfo.deposits.length < MAX_DEPOSITS, \\\"Maximum deposit amount reached\\\");\\n require(_depositAmount >= minDepositAmount, \\\"Deposit amount must be greater than min deposit amount\\\");\\n require(_receiveAmount > 0, \\\"Receive amount must be greater than 0\\\");\\n\\n uint256 conversionRate = (_depositAmount * PRECISE_UNIT) / _receiveAmount;\\n uint256 depositId = depositCounter++;\\n\\n globalAccountInfo.deposits.push(depositId);\\n\\n deposits[depositId] = Deposit({\\n depositor: msg.sender,\\n wiseTag: _wiseTag,\\n receiveCurrencyId: _receiveCurrencyId,\\n depositAmount: _depositAmount,\\n remainingDeposits: _depositAmount,\\n outstandingIntentAmount: 0,\\n conversionRate: conversionRate,\\n intentHashes: new bytes32[](0),\\n verifierSigningKey: _verifierSigningKey\\n });\\n\\n usdc.transferFrom(msg.sender, address(this), _depositAmount);\\n\\n emit DepositReceived(depositId, account.accountId, _receiveCurrencyId, _depositAmount, conversionRate);\\n }\\n\\n /**\\n * @notice Signals intent to pay the depositor defined in the _depositId the _amount * deposit conversionRate off-chain\\n * in order to unlock _amount of funds on-chain. Each user can only have one outstanding intent at a time regardless of\\n * address (tracked using accountId). Caller must not be on the depositor's deny list. If there are prunable intents then\\n * they will be deleted from the deposit to be able to maintain state hygiene.\\n *\\n * @param _depositId The ID of the deposit the on-ramper intends to use for \\n * @param _amount The amount of USDC the user wants to on-ramp\\n * @param _to Address to forward funds to (can be same as onRamper)\\n */\\n function signalIntent(uint256 _depositId, uint256 _amount, address _to) external onlyRegisteredUser {\\n bytes32 onRamperId = accountRegistry.getAccountId(msg.sender);\\n Deposit storage deposit = deposits[_depositId];\\n\\n // Caller validity checks\\n require(accountRegistry.isAllowedUser(deposit.depositor, onRamperId), \\\"Onramper on depositor's denylist\\\");\\n require(\\n globalAccount[onRamperId].lastOnrampTimestamp + onRampCooldownPeriod <= block.timestamp,\\n \\\"On ramp cool down period not elapsed\\\"\\n );\\n require(globalAccount[onRamperId].currentIntentHash == bytes32(0), \\\"Intent still outstanding\\\");\\n require(accountRegistry.getAccountId(deposit.depositor) != onRamperId, \\\"Sender cannot be the depositor\\\");\\n\\n // Intent information checks\\n require(deposit.depositor != address(0), \\\"Deposit does not exist\\\");\\n require(_amount > 0, \\\"Signaled amount must be greater than 0\\\");\\n require(_amount <= maxOnRampAmount, \\\"Signaled amount must be less than max on-ramp amount\\\");\\n require(_to != address(0), \\\"Cannot send to zero address\\\");\\n\\n bytes32 intentHash = _calculateIntentHash(onRamperId, _depositId);\\n\\n if (deposit.remainingDeposits < _amount) {\\n (\\n bytes32[] memory prunableIntents,\\n uint256 reclaimableAmount\\n ) = _getPrunableIntents(_depositId);\\n\\n require(deposit.remainingDeposits + reclaimableAmount >= _amount, \\\"Not enough liquidity\\\");\\n\\n _pruneIntents(deposit, prunableIntents);\\n deposit.remainingDeposits += reclaimableAmount;\\n deposit.outstandingIntentAmount -= reclaimableAmount;\\n }\\n\\n intents[intentHash] = Intent({\\n onRamper: msg.sender,\\n to: _to,\\n deposit: _depositId,\\n amount: _amount,\\n intentTimestamp: block.timestamp\\n });\\n\\n globalAccount[onRamperId].currentIntentHash = intentHash;\\n\\n deposit.remainingDeposits -= _amount;\\n deposit.outstandingIntentAmount += _amount;\\n deposit.intentHashes.push(intentHash);\\n\\n emit IntentSignaled(intentHash, _depositId, onRamperId, _to, _amount, block.timestamp);\\n }\\n\\n /**\\n * @notice Only callable by the originator of the intent. Cancels an outstanding intent thus allowing user to signal a new\\n * intent. Deposit state is updated to reflect the cancelled intent.\\n *\\n * @param _intentHash Hash of intent being cancelled\\n */\\n function cancelIntent(bytes32 _intentHash) external {\\n Intent memory intent = intents[_intentHash];\\n \\n require(intent.intentTimestamp != 0, \\\"Intent does not exist\\\");\\n require(\\n accountRegistry.getAccountId(intent.onRamper) == accountRegistry.getAccountId(msg.sender),\\n \\\"Sender must be the on-ramper\\\"\\n );\\n\\n Deposit storage deposit = deposits[intent.deposit];\\n\\n _pruneIntent(deposit, _intentHash);\\n\\n deposit.remainingDeposits += intent.amount;\\n deposit.outstandingIntentAmount -= intent.amount;\\n }\\n\\n /**\\n * @notice Anyone can submit an on-ramp transaction, even if caller isn't on-ramper. Upon submission the proof is validated,\\n * intent is removed, and deposit state is updated. USDC is transferred to the on-ramper.\\n *\\n * @param _sendData Struct containing unredacted data from API call to Wise\\n * @param _verifierSignature Signature by verifier of the unredacted data\\n */\\n function onRamp(\\n IWiseSendProcessor.SendData calldata _sendData,\\n bytes calldata _verifierSignature\\n )\\n external\\n {\\n (\\n Intent memory intent,\\n Deposit storage deposit,\\n bytes32 intentHash\\n ) = _verifyOnRampProof(_sendData, _verifierSignature);\\n\\n _pruneIntent(deposit, intentHash);\\n\\n deposit.outstandingIntentAmount -= intent.amount;\\n globalAccount[accountRegistry.getAccountId(intent.onRamper)].lastOnrampTimestamp = block.timestamp;\\n _closeDepositIfNecessary(intent.deposit, deposit);\\n\\n _transferFunds(intentHash, intent);\\n }\\n\\n /**\\n * @notice Allows off-ramper to release funds to the on-ramper in case of a failed on-ramp or because of some other arrangement\\n * between the two parties. Upon submission we check to make sure the msg.sender is the depositor, the intent is removed, and \\n * deposit state is updated. USDC is transferred to the on-ramper.\\n *\\n * @param _intentHash Hash of intent to resolve by releasing the funds\\n */\\n function releaseFundsToOnramper(bytes32 _intentHash) external {\\n Intent memory intent = intents[_intentHash];\\n Deposit storage deposit = deposits[intent.deposit];\\n\\n require(intent.onRamper != address(0), \\\"Intent does not exist\\\");\\n require(deposit.depositor == msg.sender, \\\"Caller must be the depositor\\\");\\n\\n _pruneIntent(deposit, _intentHash);\\n\\n deposit.outstandingIntentAmount -= intent.amount;\\n globalAccount[accountRegistry.getAccountId(intent.onRamper)].lastOnrampTimestamp = block.timestamp;\\n _closeDepositIfNecessary(intent.deposit, deposit);\\n\\n _transferFunds(_intentHash, intent);\\n }\\n\\n /**\\n * @notice Caller must be the depositor for each depositId in the array, if not whole function fails. Depositor is returned all\\n * remaining deposits and any outstanding intents that are expired. If an intent is not expired then those funds will not be\\n * returned. Deposit will be deleted as long as there are no more outstanding intents.\\n *\\n * @param _depositIds Array of depositIds the depositor is attempting to withdraw\\n */\\n function withdrawDeposit(uint256[] memory _depositIds) external {\\n uint256 returnAmount;\\n\\n for (uint256 i = 0; i < _depositIds.length; ++i) {\\n uint256 depositId = _depositIds[i];\\n Deposit storage deposit = deposits[depositId];\\n\\n require(deposit.depositor == msg.sender, \\\"Sender must be the depositor\\\");\\n\\n (\\n bytes32[] memory prunableIntents,\\n uint256 reclaimableAmount\\n ) = _getPrunableIntents(depositId);\\n\\n _pruneIntents(deposit, prunableIntents);\\n\\n returnAmount += deposit.remainingDeposits + reclaimableAmount;\\n \\n deposit.outstandingIntentAmount -= reclaimableAmount;\\n\\n emit DepositWithdrawn(depositId, deposit.depositor, deposit.remainingDeposits + reclaimableAmount);\\n \\n delete deposit.remainingDeposits;\\n _closeDepositIfNecessary(depositId, deposit);\\n }\\n\\n usdc.transfer(msg.sender, returnAmount);\\n }\\n\\n /* ============ Governance Functions ============ */\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the send processor address used for validating and interpreting zk proofs.\\n *\\n * @param _sendProcessor New send proccesor address\\n */\\n function setSendProcessor(IWiseSendProcessor _sendProcessor) external onlyOwner {\\n sendProcessor = _sendProcessor;\\n emit NewSendProcessorSet(address(_sendProcessor));\\n }\\n\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the minimum deposit amount a user can specify for off-ramping.\\n *\\n * @param _minDepositAmount The new minimum deposit amount\\n */\\n function setMinDepositAmount(uint256 _minDepositAmount) external onlyOwner {\\n require(_minDepositAmount != 0, \\\"Minimum deposit cannot be zero\\\");\\n\\n minDepositAmount = _minDepositAmount;\\n emit MinDepositAmountSet(_minDepositAmount);\\n }\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the sustainability fee. This fee is charged to on-rampers upon a successful on-ramp.\\n *\\n * @param _fee The new sustainability fee in precise units (10**18, ie 10% = 1e17)\\n */\\n function setSustainabilityFee(uint256 _fee) external onlyOwner {\\n require(_fee <= MAX_SUSTAINABILITY_FEE, \\\"Fee cannot be greater than max fee\\\");\\n\\n sustainabilityFee = _fee;\\n emit SustainabilityFeeUpdated(_fee);\\n }\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the recepient of sustainability fees.\\n *\\n * @param _feeRecipient The new fee recipient address\\n */\\n function setSustainabilityFeeRecipient(address _feeRecipient) external onlyOwner {\\n require(_feeRecipient != address(0), \\\"Fee recipient cannot be zero address\\\");\\n\\n sustainabilityFeeRecipient = _feeRecipient;\\n emit SustainabilityFeeRecipientUpdated(_feeRecipient);\\n }\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the max amount allowed to be on-ramped in each transaction. To on-ramp more than\\n * this amount a user must make multiple transactions.\\n *\\n * @param _maxOnRampAmount The new max on ramp amount\\n */\\n function setMaxOnRampAmount(uint256 _maxOnRampAmount) external onlyOwner {\\n require(_maxOnRampAmount != 0, \\\"Max on ramp amount cannot be zero\\\");\\n\\n maxOnRampAmount = _maxOnRampAmount;\\n emit MaxOnRampAmountSet(_maxOnRampAmount);\\n }\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the on-ramp cooldown period, once an on-ramp transaction is completed the user must wait this\\n * amount of time before they can signalIntent to on-ramp again.\\n *\\n * @param _onRampCooldownPeriod New on-ramp cooldown period\\n */\\n function setOnRampCooldownPeriod(uint256 _onRampCooldownPeriod) external onlyOwner {\\n onRampCooldownPeriod = _onRampCooldownPeriod;\\n emit OnRampCooldownPeriodSet(_onRampCooldownPeriod);\\n }\\n\\n /**\\n * @notice GOVERNANCE ONLY: Updates the intent expiration period, after this period elapses an intent can be pruned to prevent\\n * locking up a depositor's funds.\\n *\\n * @param _intentExpirationPeriod New intent expiration period\\n */\\n function setIntentExpirationPeriod(uint256 _intentExpirationPeriod) external onlyOwner {\\n require(_intentExpirationPeriod != 0, \\\"Max intent expiration period cannot be zero\\\");\\n\\n intentExpirationPeriod = _intentExpirationPeriod;\\n emit IntentExpirationPeriodSet(_intentExpirationPeriod);\\n }\\n\\n\\n /* ============ External View Functions ============ */\\n\\n function getDeposit(uint256 _depositId) external view returns (Deposit memory) {\\n return deposits[_depositId];\\n }\\n\\n function getIdCurrentIntentHash(address _account) public view returns (bytes32) {\\n return globalAccount[accountRegistry.getAccountId(_account)].currentIntentHash;\\n }\\n\\n function getIdCurrentIntentHashAsUint(address _account) external view returns (uint256) {\\n return uint256(getIdCurrentIntentHash(_account));\\n }\\n\\n function getLastOnRampTimestamp(address _account) external view returns (uint256) {\\n return globalAccount[accountRegistry.getAccountId(_account)].lastOnrampTimestamp;\\n }\\n\\n function getIntentsWithOnRamperId(bytes32[] calldata _intentHashes) external view returns (IntentWithOnRamperId[] memory) {\\n IntentWithOnRamperId[] memory intentsWithOnRamperId = new IntentWithOnRamperId[](_intentHashes.length);\\n\\n for (uint256 i = 0; i < _intentHashes.length; ++i) {\\n bytes32 intentHash = _intentHashes[i];\\n Intent memory intent = intents[intentHash];\\n intentsWithOnRamperId[i] = IntentWithOnRamperId({\\n intentHash: _intentHashes[i],\\n intent: intent,\\n onRamperId: accountRegistry.getAccountId(intent.onRamper)\\n });\\n }\\n\\n return intentsWithOnRamperId;\\n }\\n\\n function getAccountDeposits(address _account) external view returns (DepositWithAvailableLiquidity[] memory accountDeposits) {\\n uint256[] memory accountDepositIds = globalAccount[accountRegistry.getAccountId(_account)].deposits;\\n accountDeposits = new DepositWithAvailableLiquidity[](accountDepositIds.length);\\n \\n for (uint256 i = 0; i < accountDepositIds.length; ++i) {\\n uint256 depositId = accountDepositIds[i];\\n Deposit memory deposit = deposits[depositId];\\n ( , uint256 reclaimableAmount) = _getPrunableIntents(depositId);\\n\\n accountDeposits[i] = DepositWithAvailableLiquidity({\\n depositId: depositId,\\n depositorId: accountRegistry.getAccountId(deposit.depositor),\\n deposit: deposit,\\n availableLiquidity: deposit.remainingDeposits + reclaimableAmount\\n });\\n }\\n }\\n\\n function getDepositFromIds(uint256[] memory _depositIds) external view returns (DepositWithAvailableLiquidity[] memory depositArray) {\\n depositArray = new DepositWithAvailableLiquidity[](_depositIds.length);\\n\\n for (uint256 i = 0; i < _depositIds.length; ++i) {\\n uint256 depositId = _depositIds[i];\\n Deposit memory deposit = deposits[depositId];\\n ( , uint256 reclaimableAmount) = _getPrunableIntents(depositId);\\n\\n depositArray[i] = DepositWithAvailableLiquidity({\\n depositId: depositId,\\n depositorId: accountRegistry.getAccountId(deposit.depositor),\\n deposit: deposit,\\n availableLiquidity: deposit.remainingDeposits + reclaimableAmount\\n });\\n }\\n\\n return depositArray;\\n }\\n\\n /* ============ Internal Functions ============ */\\n\\n /**\\n * @notice Calculates the intentHash of new intent\\n */\\n function _calculateIntentHash(\\n bytes32 _accountId,\\n uint256 _depositId\\n )\\n internal\\n view\\n virtual\\n returns (bytes32 intentHash)\\n {\\n // Mod with circom prime field to make sure it fits in a 254-bit field\\n uint256 intermediateHash = uint256(keccak256(abi.encodePacked(_accountId, _depositId, block.timestamp)));\\n intentHash = bytes32(intermediateHash % CIRCOM_PRIME_FIELD);\\n }\\n\\n /**\\n * @notice Cycles through all intents currently open on a deposit and sees if any have expired. If they have expired\\n * the outstanding amounts are summed and returned alongside the intentHashes\\n */\\n function _getPrunableIntents(\\n uint256 _depositId\\n )\\n internal\\n view\\n returns(bytes32[] memory prunableIntents, uint256 reclaimedAmount)\\n {\\n bytes32[] memory intentHashes = deposits[_depositId].intentHashes;\\n prunableIntents = new bytes32[](intentHashes.length);\\n\\n for (uint256 i = 0; i < intentHashes.length; ++i) {\\n Intent memory intent = intents[intentHashes[i]];\\n if (intent.intentTimestamp + intentExpirationPeriod < block.timestamp) {\\n prunableIntents[i] = intentHashes[i];\\n reclaimedAmount += intent.amount;\\n }\\n }\\n }\\n\\n function _pruneIntents(Deposit storage _deposit, bytes32[] memory _intents) internal {\\n for (uint256 i = 0; i < _intents.length; ++i) {\\n if (_intents[i] != bytes32(0)) {\\n _pruneIntent(_deposit, _intents[i]);\\n }\\n }\\n }\\n\\n /**\\n * @notice Pruning an intent involves deleting its state from the intents mapping, zeroing out the intendee's currentIntentHash in\\n * their global account mapping, and deleting the intentHash from the deposit's intentHashes array.\\n */\\n function _pruneIntent(Deposit storage _deposit, bytes32 _intentHash) internal {\\n Intent memory intent = intents[_intentHash];\\n\\n delete globalAccount[accountRegistry.getAccountId(intent.onRamper)].currentIntentHash;\\n delete intents[_intentHash];\\n _deposit.intentHashes.removeStorage(_intentHash);\\n\\n emit IntentPruned(_intentHash, intent.deposit);\\n }\\n\\n /**\\n * @notice Removes a deposit if no outstanding intents AND no remaining deposits. Deleting a deposit deletes it from the\\n * deposits mapping and removes tracking it in the user's accounts mapping.\\n */\\n function _closeDepositIfNecessary(uint256 _depositId, Deposit storage _deposit) internal {\\n uint256 openDepositAmount = _deposit.outstandingIntentAmount + _deposit.remainingDeposits;\\n if (openDepositAmount == 0) {\\n globalAccount[accountRegistry.getAccountId(_deposit.depositor)].deposits.removeStorage(_depositId);\\n emit DepositClosed(_depositId, _deposit.depositor);\\n delete deposits[_depositId];\\n }\\n }\\n\\n /**\\n * @notice Checks if sustainability fee has been defined, if so sends fee to the fee recipient and intent amount minus fee\\n * to the on-ramper. If sustainability fee is undefined then full intent amount is transferred to on-ramper.\\n */\\n function _transferFunds(bytes32 _intentHash, Intent memory _intent) internal {\\n uint256 fee;\\n if (sustainabilityFee != 0) {\\n fee = (_intent.amount * sustainabilityFee) / PRECISE_UNIT;\\n usdc.transfer(sustainabilityFeeRecipient, fee);\\n }\\n\\n uint256 onRampAmount = _intent.amount - fee;\\n usdc.transfer(_intent.to, onRampAmount);\\n\\n emit IntentFulfilled(_intentHash, _intent.deposit, _intent.onRamper, _intent.to, onRampAmount, fee);\\n }\\n\\n /**\\n * @notice Validate send payment email and check that it hasn't already been used (done on SendProcessor).\\n * Additionally, we validate that the offRamperId matches the one from the specified intent and that enough\\n * was paid off-chain inclusive of the conversionRate.\\n */\\n function _verifyOnRampProof(\\n IWiseSendProcessor.SendData calldata _data,\\n bytes calldata _verifierSignature\\n )\\n internal\\n returns(Intent storage intent, Deposit storage deposit, bytes32 intentHash)\\n {\\n intentHash = bytes32(_data.intentHash);\\n intent = intents[intentHash];\\n require(intent.onRamper == msg.sender, \\\"Caller must be the on-ramper\\\");\\n\\n deposit = deposits[intent.deposit];\\n\\n (\\n uint256 amount,\\n uint256 timestamp,\\n bytes32 offRamperId,\\n bytes32 currencyId\\n ) = sendProcessor.processProof(\\n IWiseSendProcessor.SendProof({\\n public_values: _data,\\n proof: _verifierSignature\\n }),\\n deposit.verifierSigningKey\\n );\\n\\n require(currencyId == deposit.receiveCurrencyId, \\\"Wrong currency sent\\\");\\n require(intent.intentTimestamp <= timestamp, \\\"Intent was not created before send\\\");\\n require(accountRegistry.getAccountInfo(deposit.depositor).offRampId == offRamperId, \\\"Offramper id does not match\\\");\\n require(amount >= (intent.amount * PRECISE_UNIT) / deposit.conversionRate, \\\"Payment was not enough\\\");\\n }\\n}\\n\",\"keccak256\":\"0xf0d61d3f121651104964ff8a3b6ac9a2de95494812e2cf22b30e3a6a23a2913c\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseAccountRegistry.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseAccountRegistry {\\n\\n // Each Account is tied to a Wise ID and is represented by an Ethereum address.\\n struct AccountInfo {\\n bytes32 accountId; // User's Wise account ID\\n bytes32 offRampId; // Multi-currency account ID to receive funds\\n bytes32 wiseTagHash; // Hash of user's wise tag account stored on register. Used to verify offramper's wise tag\\n }\\n\\n function getAccountInfo(address _account) external view returns (AccountInfo memory);\\n function getAccountId(address _account) external view returns (bytes32);\\n\\n function isRegisteredUser(address _account) external view returns (bool);\\n \\n function isAllowedUser(address _account, bytes32 _deniedUser) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xfaf30dc7e7dd1a0bce25c0188059b17bde3929fb473570bc8860a82ae97c5b35\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseSendProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseSendProcessor {\\n\\n struct SendData {\\n string endpoint;\\n string host;\\n string transferId;\\n string senderId;\\n string recipientId;\\n string amount;\\n string currencyId;\\n string status;\\n string timestamp;\\n uint256 intentHash;\\n }\\n\\n struct SendProof {\\n SendData public_values;\\n bytes proof;\\n }\\n\\n function processProof(\\n SendProof calldata _proof,\\n address _verifierSigningKey\\n )\\n external\\n returns(uint256, uint256, bytes32, bytes32);\\n}\\n\",\"keccak256\":\"0x019b7fbd91e5b77bd9d9eae23d2b6b4af1a7248dc2320114ce2528f4095bc4c8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162004880380380620048808339810160408190526200003491620001dd565b6200003f3362000096565b6001600160a01b038781166080526006879055600786905560098590556008849055600a839055600b80546001600160a01b0319169183169190911790556200008888620000e6565b505050505050505062000263565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620000f062000169565b6001600160a01b0381166200015b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001668162000096565b50565b6000546001600160a01b03163314620001c55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000152565b565b6001600160a01b03811681146200016657600080fd5b600080600080600080600080610100898b031215620001fb57600080fd5b88516200020881620001c7565b60208a01519098506200021b81620001c7565b8097505060408901519550606089015194506080890151935060a0890151925060c0890151915060e08901516200025281620001c7565b809150509295985092959890939650565b6080516145e56200029b600039600081816102e5015281816118d301528181611eb1015281816133b9015261346801526145e56000f3fe608060405234801561001057600080fd5b50600436106102275760003560e01c80637113476211610130578063b3c0cfa4116100b8578063e279d9641161007c578063e279d96414610540578063ecb3dc8814610549578063ecd618f014610552578063eea1d19714610572578063f2fde38b1461058557600080fd5b8063b3c0cfa4146104e1578063b3fa4c01146104f4578063d089e11a14610507578063d55f960d1461051a578063d9478d201461052d57600080fd5b80639021578a116100ff5780639021578a146104025780639087beff1461047e5780639f9fb96814610491578063a1a954b7146104b1578063b02c43d0146104ba57600080fd5b806371134762146103c3578063715018a6146103d657806371a28f69146103de5780638da5cb5b146103f157600080fd5b806342987349116101b3578063534aa07c11610182578063534aa07c1461036e578063560d9716146103815780635dd7651514610394578063645006ca146103a757806366ec8419146103b057600080fd5b8063429873491461031f578063485cc95514610332578063495223e7146103455780635081d9521461034e57600080fd5b80632a80cda3116101fa5780632a80cda314610283578063317dcc9614610296578063392e53cd146102a95780633adba28a146102cd5780633e413bee146102e057600080fd5b80630f1ef98c1461022c578063133de6cb1461025257806314ec32fa14610267578063238c84941461027a575b600080fd5b61023f61023a366004613960565b610598565b6040519081526020015b60405180910390f35b610265610260366004613960565b610627565b005b61023f610275366004613960565b610684565b61023f600a5481565b610265610291366004613984565b610711565b6102656102a4366004613984565b6107a3565b6002546102bd90600160a01b900460ff1681565b6040519015158152602001610249565b6102656102db36600461399d565b6107e0565b6103077f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610249565b61026561032d366004613984565b610ee4565b6102656103403660046139d6565b610f85565b61023f60085481565b61036161035c366004613960565b611018565b6040516102499190613b2b565b61026561037c366004613bf8565b6113d8565b61026561038f366004613c6a565b611996565b6102656103a2366004613984565b611ac5565b61023f60065481565b6102656103be366004613984565b611b64565b6102656103d1366004613d4a565b611d33565b610265611f26565b6103616103ec366004613d4a565b611f3a565b6000546001600160a01b0316610307565b61044b610410366004613984565b600560205260009081526040902080546001820154600283015460038401546004909401546001600160a01b03938416949390921692909185565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610249565b61026561048c366004613984565b612222565b6104a461049f366004613984565b6122b9565b6040516102499190613def565b61023f60095481565b6104cd6104c8366004613984565b612440565b604051610249989796959493929190613e02565b61023f6104ef366004613960565b612520565b610265610502366004613960565b612531565b600154610307906001600160a01b031681565b610265610528366004613984565b6125e9565b600b54610307906001600160a01b031681565b61023f60075481565b61023f600c5481565b610565610560366004613e5a565b612809565b6040516102499190613ece565b600254610307906001600160a01b031681565b610265610593366004613960565b612a00565b60015460405163e0b490f760e01b81526001600160a01b03838116600483015260009260039284929091169063e0b490f790602401602060405180830381865afa1580156105ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060e9190613f5e565b8152602001908152602001600020600101549050919050565b61062f612a79565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f6e7665a41605edc0d70f4b991d652755f380754eb092d81ef9ab93664778d59e906020015b60405180910390a150565b60015460405163e0b490f760e01b81526001600160a01b03838116600483015260009260039284929091169063e0b490f790602401602060405180830381865afa1580156106d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106fa9190613f5e565b815260208101919091526040016000205492915050565b610719612a79565b8060000361076e5760405162461bcd60e51b815260206004820152601e60248201527f4d696e696d756d206465706f7369742063616e6e6f74206265207a65726f000060448201526064015b60405180910390fd5b60068190556040518181527fbdde72a6d8d8b42770c9899945ccdce09d0c5c794d3326cdb2d2cca61b12a9fc90602001610679565b6107ab612a79565b60088190556040518181527f88397975d177ce5e18abf3a5fdb8de773e80673d85eeb54f48cfaf688b3d2c3e90602001610679565b600154604051631f5bdf5d60e01b81523360048201526001600160a01b0390911690631f5bdf5d90602401602060405180830381865afa158015610828573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084c9190613f77565b6108985760405162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d7573742062652072656769737465726564207573657200006044820152606401610765565b60015460405163e0b490f760e01b81523360048201526000916001600160a01b03169063e0b490f790602401602060405180830381865afa1580156108e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109059190613f5e565b60008581526004602081905260409182902060015481549351630359b09b60e31b81526001600160a01b039485169381019390935260248301859052939450929190911690631acd84d890604401602060405180830381865afa158015610970573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109949190613f77565b6109e05760405162461bcd60e51b815260206004820181905260248201527f4f6e72616d706572206f6e206465706f7369746f7227732064656e796c6973746044820152606401610765565b6008546000838152600360205260409020600101544291610a0091613faf565b1115610a5a5760405162461bcd60e51b8152602060048201526024808201527f4f6e2072616d7020636f6f6c20646f776e20706572696f64206e6f7420656c616044820152631c1cd95960e21b6064820152608401610765565b60008281526003602052604090205415610ab65760405162461bcd60e51b815260206004820152601860248201527f496e74656e74207374696c6c206f75747374616e64696e6700000000000000006044820152606401610765565b600154815460405163e0b490f760e01b81526001600160a01b0391821660048201528492919091169063e0b490f790602401602060405180830381865afa158015610b05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b299190613f5e565b03610b765760405162461bcd60e51b815260206004820152601e60248201527f53656e6465722063616e6e6f7420626520746865206465706f7369746f7200006044820152606401610765565b80546001600160a01b0316610bc65760405162461bcd60e51b815260206004820152601660248201527511195c1bdcda5d08191bd95cc81b9bdd08195e1a5cdd60521b6044820152606401610765565b60008411610c255760405162461bcd60e51b815260206004820152602660248201527f5369676e616c656420616d6f756e74206d75737420626520677265617465722060448201526507468616e20360d41b6064820152608401610765565b600754841115610c945760405162461bcd60e51b815260206004820152603460248201527f5369676e616c656420616d6f756e74206d757374206265206c657373207468616044820152731b881b585e081bdb8b5c985b5c08185b5bdd5b9d60621b6064820152608401610765565b6001600160a01b038316610cea5760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f742073656e6420746f207a65726f206164647265737300000000006044820152606401610765565b6000610cf68387612ad3565b90508482600501541015610dab57600080610d1088612b3e565b9150915086818560050154610d259190613faf565b1015610d6a5760405162461bcd60e51b81526020600482015260146024820152734e6f7420656e6f756768206c697175696469747960601b6044820152606401610765565b610d748483612ce5565b80846005016000828254610d889190613faf565b9250508190555080846006016000828254610da39190613fc2565b909155505050505b6040805160a0810182523381526001600160a01b0386811660208084019182528385018b8152606085018b8152426080870190815260008981526005808652898220985189549089166001600160a01b0319918216178a55965160018a01805491909916971696909617909655915160028701555160038087019190915590516004909501949094558783529290925291822083905583018054879290610e53908490613fc2565b9250508190555084826006016000828254610e6e9190613faf565b9091555050600882018054600181018255600091825260209182902001829055604080516001600160a01b038716815291820187905242908201528390879083907f1a1292e170a0f000ccf956afba79bee0f9ec1d81f3f901c1d4d11e1f336aae109060600160405180910390a4505050505050565b610eec612a79565b80600003610f505760405162461bcd60e51b815260206004820152602b60248201527f4d617820696e74656e742065787069726174696f6e20706572696f642063616e60448201526a6e6f74206265207a65726f60a81b6064820152608401610765565b60098190556040518181527f55e3f6b95de9a0ec782f892e93fafe4e56be0696df204ddf8e0a40a9a713a80390602001610679565b610f8d612a79565b600254600160a01b900460ff1615610fdd5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610765565b600180546001600160a01b039384166001600160a01b0319909116179055600280546001600160a81b0319169190921617600160a01b179055565b60015460405163e0b490f760e01b81526001600160a01b0383811660048301526060926000926003928492169063e0b490f790602401602060405180830381865afa15801561106b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108f9190613f5e565b81526020019081526020016000206002018054806020026020016040519081016040528092919081815260200182805480156110ea57602002820191906000526020600020905b8154815260200190600101908083116110d6575b5050505050905080516001600160401b0381111561110a5761110a613cdb565b60405190808252806020026020018201604052801561114357816020015b61113061380a565b8152602001906001900390816111285790505b50915060005b81518110156113d157600082828151811061116657611166613fd5565b60209081029190910181015160008181526004835260408082208151610120810190925280546001600160a01b0316825260018101805494965092949193909291840191906111b490613feb565b80601f01602080910402602001604051908101604052809291908181526020018280546111e090613feb565b801561122d5780601f106112025761010080835404028352916020019161122d565b820191906000526020600020905b81548152906001019060200180831161121057829003601f168201915b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882018054806020026020016040519081016040528092919081815260200182805480156112e657602002820191906000526020600020905b8154815260200190600101908083116112d2575b505050505081525050905060006112fc83612b3e565b604080516080810182528681526001548651925163e0b490f760e01b81526001600160a01b039384166004820152939550909350602084019291169063e0b490f790602401602060405180830381865afa15801561135e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113829190613f5e565b8152602001838152602001828460a0015161139d9190613faf565b8152508685815181106113b2576113b2613fd5565b6020026020010181905250505050806113ca9061401f565b9050611149565b5050919050565b600154604051631f5bdf5d60e01b81523360048201526001600160a01b0390911690631f5bdf5d90602401602060405180830381865afa158015611420573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114449190613f77565b6114905760405162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d7573742062652072656769737465726564207573657200006044820152606401610765565b600154604051630f6a21fd60e31b81523360048201526000916001600160a01b031690637b510fe890602401606060405180830381865afa1580156114d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114fd9190614038565b8051600090815260036020908152604090912090820151919250906115645760405162461bcd60e51b815260206004820181905260248201527f4d7573742062652072656769737465726564206173206f66662072616d7065726044820152606401610765565b8160400151888860405160200161157c929190614093565b60405160208183030381529060405280519060200120146115f35760405162461bcd60e51b815260206004820152602b60248201527f576973652074616720646f6573206e6f74206d6174636820726567697374657260448201526a656420776973652074616760a81b6064820152608401610765565b60028101546005116116475760405162461bcd60e51b815260206004820152601e60248201527f4d6178696d756d206465706f73697420616d6f756e74207265616368656400006044820152606401610765565b6006548510156116b85760405162461bcd60e51b815260206004820152603660248201527f4465706f73697420616d6f756e74206d757374206265206772656174657220746044820152751a185b881b5a5b8819195c1bdcda5d08185b5bdd5b9d60521b6064820152608401610765565b600084116117165760405162461bcd60e51b815260206004820152602560248201527f5265636569766520616d6f756e74206d75737420626520677265617465722074604482015264068616e20360dc1b6064820152608401610765565b60008461172b670de0b6b3a7640000886140c2565b61173591906140ef565b600c8054919250600091908261174a8361401f565b9091555060028401805460018101825560009182526020918290200182905560408051610120810182523381528151601f8e018490048402810184019092528c8252929350828201918d908d908190840183828082843760009201829052509385525050506001600160a01b03881660208084019190915260408084018c9052606084018d9052608084018c905260a0840183905260c084018790528051838152918201905260e090920191905090526000828152600460209081526040909120825181546001600160a01b0319166001600160a01b0390911617815590820151600182019061183a9082614149565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e0820151600782015561010082015180516118af916008840191602090910190613836565b50506040516323b872dd60e01b8152336004820152306024820152604481018990527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691506323b872dd906064016020604051808303816000875af1158015611925573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119499190613f77565b50835160408051898152602081018590528a929184917f94c4b6f8843ea372709c89bc4a9ed85ef74ab10a68713ffdddc31716a76a6c95910160405180910390a450505050505050505050565b60008060006119a6868686612d47565b6040805160a08101825284546001600160a01b0390811682526001860154166020820152600285015491810191909152600384015460608201526004909301546080840152919450925090506119fc828261309d565b8260600151826006016000828254611a149190613fc2565b9091555050600154835160405163e0b490f760e01b81526001600160a01b039182166004820152429260039260009291169063e0b490f790602401602060405180830381865afa158015611a6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a909190613f5e565b815260200190815260200160002060010181905550611ab38360400151836131e6565b611abd818461335c565b505050505050565b611acd612a79565b66b1a2bc2ec50000811115611b2f5760405162461bcd60e51b815260206004820152602260248201527f4665652063616e6e6f742062652067726561746572207468616e206d61782066604482015261656560f01b6064820152608401610765565b600a8190556040518181527f44f48e1b871e6db1e909a7b253b054b7150a0b4ddf4d59b159c827d82e72567090602001610679565b6000818152600560209081526040808320815160a08101835281546001600160a01b03908116825260018301548116828601526002830154828501819052600384015460608401526004938401546080840152865291909352922081519192909116611c0a5760405162461bcd60e51b8152602060048201526015602482015274125b9d195b9d08191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606401610765565b80546001600160a01b03163314611c635760405162461bcd60e51b815260206004820152601c60248201527f43616c6c6572206d75737420626520746865206465706f7369746f72000000006044820152606401610765565b611c6d818461309d565b8160600151816006016000828254611c859190613fc2565b9091555050600154825160405163e0b490f760e01b81526001600160a01b039182166004820152429260039260009291169063e0b490f790602401602060405180830381865afa158015611cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d019190613f5e565b815260200190815260200160002060010181905550611d248260400151826131e6565b611d2e838361335c565b505050565b6000805b8251811015611e94576000838281518110611d5457611d54613fd5565b6020908102919091018101516000818152600490925260409091208054919250906001600160a01b03163314611dcc5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206d75737420626520746865206465706f7369746f72000000006044820152606401610765565b600080611dd884612b3e565b91509150611de68383612ce5565b808360050154611df69190613faf565b611e009087613faf565b955080836006016000828254611e169190613fc2565b9091555050825460058401546001600160a01b039091169085907fae1f357660ab777dcfd38c0ab6357834684ec26289ecfa07ec65dbf6c3c6431290611e5d908590613faf565b60405190815260200160405180910390a360006005840155611e7f84846131e6565b5050505080611e8d9061401f565b9050611d37565b5060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015611f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2e9190613f77565b611f2e612a79565b611f38600061353a565b565b606081516001600160401b03811115611f5557611f55613cdb565b604051908082528060200260200182016040528015611f8e57816020015b611f7b61380a565b815260200190600190039081611f735790505b50905060005b825181101561221c576000838281518110611fb157611fb1613fd5565b60209081029190910181015160008181526004835260408082208151610120810190925280546001600160a01b031682526001810180549496509294919390929184019190611fff90613feb565b80601f016020809104026020016040519081016040528092919081815260200182805461202b90613feb565b80156120785780601f1061204d57610100808354040283529160200191612078565b820191906000526020600020905b81548152906001019060200180831161205b57829003601f168201915b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820180548060200260200160405190810160405280929190818152602001828054801561213157602002820191906000526020600020905b81548152602001906001019080831161211d575b5050505050815250509050600061214783612b3e565b604080516080810182528681526001548651925163e0b490f760e01b81526001600160a01b039384166004820152939550909350602084019291169063e0b490f790602401602060405180830381865afa1580156121a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121cd9190613f5e565b8152602001838152602001828460a001516121e89190613faf565b8152508585815181106121fd576121fd613fd5565b6020026020010181905250505050806122159061401f565b9050611f94565b50919050565b61222a612a79565b806000036122845760405162461bcd60e51b815260206004820152602160248201527f4d6178206f6e2072616d7020616d6f756e742063616e6e6f74206265207a65726044820152606f60f81b6064820152608401610765565b60078190556040518181527fcab6b49ca21dd111cf4a55d507bbe89dd12d69216e28247060d4b2163ca41b3990602001610679565b6122c1613881565b6000828152600460209081526040918290208251610120810190935280546001600160a01b0316835260018101805491928401916122fe90613feb565b80601f016020809104026020016040519081016040528092919081815260200182805461232a90613feb565b80156123775780601f1061234c57610100808354040283529160200191612377565b820191906000526020600020905b81548152906001019060200180831161235a57829003601f168201915b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820180548060200260200160405190810160405280929190818152602001828054801561243057602002820191906000526020600020905b81548152602001906001019080831161241c575b5050505050815250509050919050565b600460205260009081526040902080546001820180546001600160a01b03909216929161246c90613feb565b80601f016020809104026020016040519081016040528092919081815260200182805461249890613feb565b80156124e55780601f106124ba576101008083540402835291602001916124e5565b820191906000526020600020905b8154815290600101906020018083116124c857829003601f168201915b5050506002840154600385015460048601546005870154600688015460079098015496976001600160a01b0390941696929550909350919088565b600061252b82610684565b92915050565b612539612a79565b6001600160a01b03811661259b5760405162461bcd60e51b8152602060048201526024808201527f46656520726563697069656e742063616e6e6f74206265207a65726f206164646044820152637265737360e01b6064820152608401610765565b600b80546001600160a01b0319166001600160a01b0383169081179091556040519081527f594ad6ee98bfc0c73e6d15fd4e762502f359e05d26907b7fa1ff82eb5e99f6e490602001610679565b6000818152600560209081526040808320815160a08101835281546001600160a01b039081168252600183015416938101939093526002810154918301919091526003810154606083015260040154608082018190529091036126865760405162461bcd60e51b8152602060048201526015602482015274125b9d195b9d08191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606401610765565b60015460405163e0b490f760e01b81523360048201526001600160a01b039091169063e0b490f790602401602060405180830381865afa1580156126ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126f29190613f5e565b600154825160405163e0b490f760e01b81526001600160a01b03918216600482015291169063e0b490f790602401602060405180830381865afa15801561273d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127619190613f5e565b146127ae5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206d75737420626520746865206f6e2d72616d706572000000006044820152606401610765565b60408082015160009081526004602052206127c9818461309d565b81606001518160050160008282546127e19190613faf565b909155505060608201516006820180546000906127ff908490613fc2565b9091555050505050565b60606000826001600160401b0381111561282557612825613cdb565b60405190808252806020026020018201604052801561289f57816020015b61288c60408051606080820183526000808352835160a0810185528181526020818101839052948101829052918201819052608082015290918201908152600060209091015290565b8152602001906001900390816128435790505b50905060005b838110156129f85760008585838181106128c1576128c1613fd5565b60209081029290920135600081815260058452604090819020815160a08101835281546001600160a01b0390811682526001830154169581019590955260028101548583015260038101546060808701919091526004909101546080860152815190810190915290935090508088888681811061294057612940613fd5565b60209081029290920135835250810183905260015483516040805163e0b490f760e01b81526001600160a01b03928316600482015293019291169063e0b490f790602401602060405180830381865afa1580156129a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c59190613f5e565b8152508484815181106129da576129da613fd5565b60200260200101819052505050806129f19061401f565b90506128a5565b509392505050565b612a08612a79565b6001600160a01b038116612a6d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610765565b612a768161353a565b50565b6000546001600160a01b03163314611f385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610765565b6040805160208101849052908101829052426060820152600090819060800160408051601f1981840301815291905280516020909101209050612b367f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182614208565b949350505050565b60008181526004602090815260408083206008018054825181850281018501909352808352606094938493929190830182828015612b9b57602002820191906000526020600020905b815481526020019060010190808311612b87575b5050505050905080516001600160401b03811115612bbb57612bbb613cdb565b604051908082528060200260200182016040528015612be4578160200160208202803683370190505b50925060005b8151811015612cde57600060056000848481518110612c0b57612c0b613fd5565b6020908102919091018101518252818101929092526040908101600020815160a08101835281546001600160a01b039081168252600183015416938101939093526002810154918301919091526003810154606083015260040154608082018190526009549192504291612c7e91613faf565b1015612ccd57828281518110612c9657612c96613fd5565b6020026020010151858381518110612cb057612cb0613fd5565b60209081029190910101526060810151612cca9085613faf565b93505b50612cd78161401f565b9050612bea565b5050915091565b60005b8151811015611d2e576000801b828281518110612d0757612d07613fd5565b602002602001015114612d3757612d3783838381518110612d2a57612d2a613fd5565b602002602001015161309d565b612d408161401f565b9050612ce8565b610120830135600081815260056020526040812080549092906001600160a01b03163314612db75760405162461bcd60e51b815260206004820152601c60248201527f43616c6c6572206d75737420626520746865206f6e2d72616d706572000000006044820152606401610765565b6002808401546000908152600460205260408082209254815180830190925292945090918291829182916001600160a01b039091169063f20333c19080612dfd8e61428b565b81526020018c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505091525060028901546040516001600160e01b031960e085901b168152612e6a92916001600160a01b03169060040161440b565b6080604051808303816000875af1158015612e89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ead9190614563565b935093509350935085600401548114612efe5760405162461bcd60e51b815260206004820152601360248201527215dc9bdb99c818dd5c9c995b98de481cd95b9d606a1b6044820152606401610765565b8287600401541115612f5d5760405162461bcd60e51b815260206004820152602260248201527f496e74656e7420776173206e6f742063726561746564206265666f72652073656044820152611b9960f21b6064820152608401610765565b6001548654604051630f6a21fd60e31b81526001600160a01b03918216600482015284929190911690637b510fe890602401606060405180830381865afa158015612fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd09190614038565b60200151146130215760405162461bcd60e51b815260206004820152601b60248201527f4f666672616d70657220696420646f6573206e6f74206d6174636800000000006044820152606401610765565b8560070154670de0b6b3a7640000886003015461303e91906140c2565b61304891906140ef565b8410156130905760405162461bcd60e51b81526020600482015260166024820152750a0c2f2dacadce840eec2e640dcdee840cadcdeeaced60531b6044820152606401610765565b5050505093509350939050565b6000818152600560209081526040808320815160a08101835281546001600160a01b03908116808352600180850154831696840196909652600284015483860152600380850154606085015260049485015460808501529554945163e0b490f760e01b815293840152909492169063e0b490f790602401602060405180830381865afa158015613131573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131559190613f5e565b8152602080820192909252604090810160009081208190558481526005909252812080546001600160a01b0319908116825560018201805490911690556002810182905560038101829055600401556131b1600884018361358a565b604080820151905183907fe8a865b4bab023c399cbd1f2cdd0df2199beb6e5012a4bd2d7691cf7e4199d5a90600090a3505050565b6000816005015482600601546131fc9190613faf565b905080600003611d2e57600154825460405163e0b490f760e01b81526001600160a01b0391821660048201526132a2928692600392600092919091169063e0b490f790602401602060405180830381865afa15801561325f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132839190613f5e565b81526020019081526020016000206002016136b290919063ffffffff16565b8154604080518581526001600160a01b0390921660208301527f8ac07cc6e38c6222dd0309c80353c1962354bacf222b825d7401cc80e93ff3cc910160405180910390a1600083815260046020526040812080546001600160a01b03191681559061331060018301826138e2565b6002820180546001600160a01b03191690556000600383018190556004830181905560058301819055600683018190556007830181905561335590600884019061391c565b5050505050565b6000600a5460001461342857670de0b6b3a7640000600a54836060015161338391906140c2565b61338d91906140ef565b600b5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015613402573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134269190613f77565b505b600081836060015161343a9190613fc2565b602084015160405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156134b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d59190613f77565b50825160408085015160208087015183516001600160a01b03918216815291820186905292810186905291909216919086907ffa03438194e61c243c6bb5349f1e1dc674431b86f119b5e3b2b327bc43446bce9060600160405180910390a450505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806135e6848054806020026020016040519081016040528092919081815260200182805480156135db57602002820191906000526020600020905b8154815260200190600101908083116135c7575b505050505084613757565b915091508061362f5760405162461bcd60e51b8152602060048201526015602482015274313cba32b99999103737ba1034b71030b93930bc9760591b6044820152606401610765565b835460009061364090600190613fc2565b90508083146136855784818154811061365b5761365b613fd5565b906000526020600020015485848154811061367857613678613fd5565b6000918252602090912001555b8480548061369557613695614599565b600190038181906000526020600020016000905590555050505050565b60008061370e8480548060200260200160405190810160405280929190818152602001828054801561370357602002820191906000526020600020905b8154815260200190600101908083116136ef575b5050505050846137ba565b915091508061362f5760405162461bcd60e51b81526020600482015260156024820152743ab4b73a191a9b103737ba1034b71030b93930bc9760591b6044820152606401610765565b81516000908190815b818110156137a7578486828151811061377b5761377b613fd5565b602002602001015103613795579250600191506137b39050565b8061379f8161401f565b915050613760565b50600019600092509250505b9250929050565b81516000908190815b818110156137a757848682815181106137de576137de613fd5565b6020026020010151036137f8579250600191506137b39050565b806138028161401f565b9150506137c3565b6040805160808101825260008082526020820152908101613829613881565b8152602001600081525090565b828054828255906000526020600020908101928215613871579160200282015b82811115613871578251825591602001919060010190613856565b5061387d929150613936565b5090565b60405180610120016040528060006001600160a01b031681526020016060815260200160006001600160a01b031681526020016000815260200160008019168152602001600081526020016000815260200160008152602001606081525090565b5080546138ee90613feb565b6000825580601f106138fe575050565b601f016020900490600052602060002090810190612a769190613936565b5080546000825590600052602060002090810190612a7691905b5b8082111561387d5760008155600101613937565b6001600160a01b0381168114612a7657600080fd5b60006020828403121561397257600080fd5b813561397d8161394b565b9392505050565b60006020828403121561399657600080fd5b5035919050565b6000806000606084860312156139b257600080fd5b833592506020840135915060408401356139cb8161394b565b809150509250925092565b600080604083850312156139e957600080fd5b82356139f48161394b565b91506020830135613a048161394b565b809150509250929050565b6000815180845260005b81811015613a3557602081850181015186830182015201613a19565b506000602082860101526020601f19601f83011685010191505092915050565b600081518084526020808501945080840160005b83811015613a8557815187529582019590820190600101613a69565b509495945050505050565b80516001600160a01b0316825260006101206020830151816020860152613ab982860182613a0f565b9150506040830151613ad660408601826001600160a01b03169052565b50606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e083015160e08501526101008084015185830382870152613b218382613a55565b9695505050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015613ba957603f1989840301855281516080815185528882015189860152878201518189870152613b8882870182613a90565b60609384015196909301959095525094870194925090860190600101613b52565b509098975050505050505050565b60008083601f840112613bc957600080fd5b5081356001600160401b03811115613be057600080fd5b6020830191508360208285010111156137b357600080fd5b60008060008060008060a08789031215613c1157600080fd5b86356001600160401b03811115613c2757600080fd5b613c3389828a01613bb7565b9097509550506020870135935060408701359250606087013591506080870135613c5c8161394b565b809150509295509295509295565b600080600060408486031215613c7f57600080fd5b83356001600160401b0380821115613c9657600080fd5b908501906101408288031215613cab57600080fd5b90935060208501359080821115613cc157600080fd5b50613cce86828701613bb7565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405161014081016001600160401b0381118282101715613d1457613d14613cdb565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613d4257613d42613cdb565b604052919050565b60006020808385031215613d5d57600080fd5b82356001600160401b0380821115613d7457600080fd5b818501915085601f830112613d8857600080fd5b813581811115613d9a57613d9a613cdb565b8060051b9150613dab848301613d1a565b8181529183018401918481019088841115613dc557600080fd5b938501935b83851015613de357843582529385019390850190613dca565b98975050505050505050565b60208152600061397d6020830184613a90565b6001600160a01b03898116825261010060208301819052600091613e288483018c613a0f565b9916604084015250506060810195909552608085019390935260a084019190915260c083015260e09091015292915050565b60008060208385031215613e6d57600080fd5b82356001600160401b0380821115613e8457600080fd5b818501915085601f830112613e9857600080fd5b813581811115613ea757600080fd5b8660208260051b8501011115613ebc57600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b82811015613f51578151805185528681015180516001600160a01b039081168988015281890151168787015286810151606080880191909152810151608080880191909152015160a086015285015160c085015260e09093019290850190600101613eeb565b5091979650505050505050565b600060208284031215613f7057600080fd5b5051919050565b600060208284031215613f8957600080fd5b8151801515811461397d57600080fd5b634e487b7160e01b600052601160045260246000fd5b8082018082111561252b5761252b613f99565b8181038181111561252b5761252b613f99565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680613fff57607f821691505b60208210810361221c57634e487b7160e01b600052602260045260246000fd5b60006001820161403157614031613f99565b5060010190565b60006060828403121561404a57600080fd5b604051606081018181106001600160401b038211171561406c5761406c613cdb565b80604052508251815260208301516020820152604083015160408201528091505092915050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b808202811582820484141761252b5761252b613f99565b634e487b7160e01b600052601260045260246000fd5b6000826140fe576140fe6140d9565b500490565b601f821115611d2e57600081815260208120601f850160051c8101602086101561412a5750805b601f850160051c820191505b81811015611abd57828155600101614136565b81516001600160401b0381111561416257614162613cdb565b614176816141708454613feb565b84614103565b602080601f8311600181146141ab57600084156141935750858301515b600019600386901b1c1916600185901b178555611abd565b600085815260208120601f198616915b828110156141da578886015182559484019460019091019084016141bb565b50858210156141f85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600082614217576142176140d9565b500690565b600082601f83011261422d57600080fd5b81356001600160401b0381111561424657614246613cdb565b614259601f8201601f1916602001613d1a565b81815284602083860101111561426e57600080fd5b816020850160208301376000918101602001919091529392505050565b6000610140823603121561429e57600080fd5b6142a6613cf1565b82356001600160401b03808211156142bd57600080fd5b6142c93683870161421c565b835260208501359150808211156142df57600080fd5b6142eb3683870161421c565b6020840152604085013591508082111561430457600080fd5b6143103683870161421c565b6040840152606085013591508082111561432957600080fd5b6143353683870161421c565b6060840152608085013591508082111561434e57600080fd5b61435a3683870161421c565b608084015260a085013591508082111561437357600080fd5b61437f3683870161421c565b60a084015260c085013591508082111561439857600080fd5b6143a43683870161421c565b60c084015260e08501359150808211156143bd57600080fd5b6143c93683870161421c565b60e0840152610100915081850135818111156143e457600080fd5b6143f03682880161421c565b92840192909252505061012092830135928101929092525090565b604081526000835160408084015280516101408060808601526144326101c0860183613a0f565b91506020830151607f19808785030160a08801526144508483613a0f565b935060408501519150808785030160c088015261446d8483613a0f565b935060608501519150808785030160e088015261448a8483613a0f565b9350608085015191506101008188860301818901526144a98584613a0f565b945060a086015192506101208289870301818a01526144c88685613a0f565b955060c087015193508289870301858a01526144e48685613a0f565b955060e0870151945082898703016101608a01526145028686613a0f565b955081870151945082898703016101808a015261451f8686613a0f565b9601516101a0890152505050506020860151848303603f1901606086015291905061454a8183613a0f565b9250505061397d60208301846001600160a01b03169052565b6000806000806080858703121561457957600080fd5b505082516020840151604085015160609095015191969095509092509050565b634e487b7160e01b600052603160045260246000fdfea264697066735822122004ea0f66a7be18f0d38eef6096cdd835afaebe0d26328cd92d300376f8d8d6b564736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102275760003560e01c80637113476211610130578063b3c0cfa4116100b8578063e279d9641161007c578063e279d96414610540578063ecb3dc8814610549578063ecd618f014610552578063eea1d19714610572578063f2fde38b1461058557600080fd5b8063b3c0cfa4146104e1578063b3fa4c01146104f4578063d089e11a14610507578063d55f960d1461051a578063d9478d201461052d57600080fd5b80639021578a116100ff5780639021578a146104025780639087beff1461047e5780639f9fb96814610491578063a1a954b7146104b1578063b02c43d0146104ba57600080fd5b806371134762146103c3578063715018a6146103d657806371a28f69146103de5780638da5cb5b146103f157600080fd5b806342987349116101b3578063534aa07c11610182578063534aa07c1461036e578063560d9716146103815780635dd7651514610394578063645006ca146103a757806366ec8419146103b057600080fd5b8063429873491461031f578063485cc95514610332578063495223e7146103455780635081d9521461034e57600080fd5b80632a80cda3116101fa5780632a80cda314610283578063317dcc9614610296578063392e53cd146102a95780633adba28a146102cd5780633e413bee146102e057600080fd5b80630f1ef98c1461022c578063133de6cb1461025257806314ec32fa14610267578063238c84941461027a575b600080fd5b61023f61023a366004613960565b610598565b6040519081526020015b60405180910390f35b610265610260366004613960565b610627565b005b61023f610275366004613960565b610684565b61023f600a5481565b610265610291366004613984565b610711565b6102656102a4366004613984565b6107a3565b6002546102bd90600160a01b900460ff1681565b6040519015158152602001610249565b6102656102db36600461399d565b6107e0565b6103077f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610249565b61026561032d366004613984565b610ee4565b6102656103403660046139d6565b610f85565b61023f60085481565b61036161035c366004613960565b611018565b6040516102499190613b2b565b61026561037c366004613bf8565b6113d8565b61026561038f366004613c6a565b611996565b6102656103a2366004613984565b611ac5565b61023f60065481565b6102656103be366004613984565b611b64565b6102656103d1366004613d4a565b611d33565b610265611f26565b6103616103ec366004613d4a565b611f3a565b6000546001600160a01b0316610307565b61044b610410366004613984565b600560205260009081526040902080546001820154600283015460038401546004909401546001600160a01b03938416949390921692909185565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610249565b61026561048c366004613984565b612222565b6104a461049f366004613984565b6122b9565b6040516102499190613def565b61023f60095481565b6104cd6104c8366004613984565b612440565b604051610249989796959493929190613e02565b61023f6104ef366004613960565b612520565b610265610502366004613960565b612531565b600154610307906001600160a01b031681565b610265610528366004613984565b6125e9565b600b54610307906001600160a01b031681565b61023f60075481565b61023f600c5481565b610565610560366004613e5a565b612809565b6040516102499190613ece565b600254610307906001600160a01b031681565b610265610593366004613960565b612a00565b60015460405163e0b490f760e01b81526001600160a01b03838116600483015260009260039284929091169063e0b490f790602401602060405180830381865afa1580156105ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060e9190613f5e565b8152602001908152602001600020600101549050919050565b61062f612a79565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f6e7665a41605edc0d70f4b991d652755f380754eb092d81ef9ab93664778d59e906020015b60405180910390a150565b60015460405163e0b490f760e01b81526001600160a01b03838116600483015260009260039284929091169063e0b490f790602401602060405180830381865afa1580156106d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106fa9190613f5e565b815260208101919091526040016000205492915050565b610719612a79565b8060000361076e5760405162461bcd60e51b815260206004820152601e60248201527f4d696e696d756d206465706f7369742063616e6e6f74206265207a65726f000060448201526064015b60405180910390fd5b60068190556040518181527fbdde72a6d8d8b42770c9899945ccdce09d0c5c794d3326cdb2d2cca61b12a9fc90602001610679565b6107ab612a79565b60088190556040518181527f88397975d177ce5e18abf3a5fdb8de773e80673d85eeb54f48cfaf688b3d2c3e90602001610679565b600154604051631f5bdf5d60e01b81523360048201526001600160a01b0390911690631f5bdf5d90602401602060405180830381865afa158015610828573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084c9190613f77565b6108985760405162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d7573742062652072656769737465726564207573657200006044820152606401610765565b60015460405163e0b490f760e01b81523360048201526000916001600160a01b03169063e0b490f790602401602060405180830381865afa1580156108e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109059190613f5e565b60008581526004602081905260409182902060015481549351630359b09b60e31b81526001600160a01b039485169381019390935260248301859052939450929190911690631acd84d890604401602060405180830381865afa158015610970573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109949190613f77565b6109e05760405162461bcd60e51b815260206004820181905260248201527f4f6e72616d706572206f6e206465706f7369746f7227732064656e796c6973746044820152606401610765565b6008546000838152600360205260409020600101544291610a0091613faf565b1115610a5a5760405162461bcd60e51b8152602060048201526024808201527f4f6e2072616d7020636f6f6c20646f776e20706572696f64206e6f7420656c616044820152631c1cd95960e21b6064820152608401610765565b60008281526003602052604090205415610ab65760405162461bcd60e51b815260206004820152601860248201527f496e74656e74207374696c6c206f75747374616e64696e6700000000000000006044820152606401610765565b600154815460405163e0b490f760e01b81526001600160a01b0391821660048201528492919091169063e0b490f790602401602060405180830381865afa158015610b05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b299190613f5e565b03610b765760405162461bcd60e51b815260206004820152601e60248201527f53656e6465722063616e6e6f7420626520746865206465706f7369746f7200006044820152606401610765565b80546001600160a01b0316610bc65760405162461bcd60e51b815260206004820152601660248201527511195c1bdcda5d08191bd95cc81b9bdd08195e1a5cdd60521b6044820152606401610765565b60008411610c255760405162461bcd60e51b815260206004820152602660248201527f5369676e616c656420616d6f756e74206d75737420626520677265617465722060448201526507468616e20360d41b6064820152608401610765565b600754841115610c945760405162461bcd60e51b815260206004820152603460248201527f5369676e616c656420616d6f756e74206d757374206265206c657373207468616044820152731b881b585e081bdb8b5c985b5c08185b5bdd5b9d60621b6064820152608401610765565b6001600160a01b038316610cea5760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f742073656e6420746f207a65726f206164647265737300000000006044820152606401610765565b6000610cf68387612ad3565b90508482600501541015610dab57600080610d1088612b3e565b9150915086818560050154610d259190613faf565b1015610d6a5760405162461bcd60e51b81526020600482015260146024820152734e6f7420656e6f756768206c697175696469747960601b6044820152606401610765565b610d748483612ce5565b80846005016000828254610d889190613faf565b9250508190555080846006016000828254610da39190613fc2565b909155505050505b6040805160a0810182523381526001600160a01b0386811660208084019182528385018b8152606085018b8152426080870190815260008981526005808652898220985189549089166001600160a01b0319918216178a55965160018a01805491909916971696909617909655915160028701555160038087019190915590516004909501949094558783529290925291822083905583018054879290610e53908490613fc2565b9250508190555084826006016000828254610e6e9190613faf565b9091555050600882018054600181018255600091825260209182902001829055604080516001600160a01b038716815291820187905242908201528390879083907f1a1292e170a0f000ccf956afba79bee0f9ec1d81f3f901c1d4d11e1f336aae109060600160405180910390a4505050505050565b610eec612a79565b80600003610f505760405162461bcd60e51b815260206004820152602b60248201527f4d617820696e74656e742065787069726174696f6e20706572696f642063616e60448201526a6e6f74206265207a65726f60a81b6064820152608401610765565b60098190556040518181527f55e3f6b95de9a0ec782f892e93fafe4e56be0696df204ddf8e0a40a9a713a80390602001610679565b610f8d612a79565b600254600160a01b900460ff1615610fdd5760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610765565b600180546001600160a01b039384166001600160a01b0319909116179055600280546001600160a81b0319169190921617600160a01b179055565b60015460405163e0b490f760e01b81526001600160a01b0383811660048301526060926000926003928492169063e0b490f790602401602060405180830381865afa15801561106b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108f9190613f5e565b81526020019081526020016000206002018054806020026020016040519081016040528092919081815260200182805480156110ea57602002820191906000526020600020905b8154815260200190600101908083116110d6575b5050505050905080516001600160401b0381111561110a5761110a613cdb565b60405190808252806020026020018201604052801561114357816020015b61113061380a565b8152602001906001900390816111285790505b50915060005b81518110156113d157600082828151811061116657611166613fd5565b60209081029190910181015160008181526004835260408082208151610120810190925280546001600160a01b0316825260018101805494965092949193909291840191906111b490613feb565b80601f01602080910402602001604051908101604052809291908181526020018280546111e090613feb565b801561122d5780601f106112025761010080835404028352916020019161122d565b820191906000526020600020905b81548152906001019060200180831161121057829003601f168201915b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882018054806020026020016040519081016040528092919081815260200182805480156112e657602002820191906000526020600020905b8154815260200190600101908083116112d2575b505050505081525050905060006112fc83612b3e565b604080516080810182528681526001548651925163e0b490f760e01b81526001600160a01b039384166004820152939550909350602084019291169063e0b490f790602401602060405180830381865afa15801561135e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113829190613f5e565b8152602001838152602001828460a0015161139d9190613faf565b8152508685815181106113b2576113b2613fd5565b6020026020010181905250505050806113ca9061401f565b9050611149565b5050919050565b600154604051631f5bdf5d60e01b81523360048201526001600160a01b0390911690631f5bdf5d90602401602060405180830381865afa158015611420573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114449190613f77565b6114905760405162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d7573742062652072656769737465726564207573657200006044820152606401610765565b600154604051630f6a21fd60e31b81523360048201526000916001600160a01b031690637b510fe890602401606060405180830381865afa1580156114d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114fd9190614038565b8051600090815260036020908152604090912090820151919250906115645760405162461bcd60e51b815260206004820181905260248201527f4d7573742062652072656769737465726564206173206f66662072616d7065726044820152606401610765565b8160400151888860405160200161157c929190614093565b60405160208183030381529060405280519060200120146115f35760405162461bcd60e51b815260206004820152602b60248201527f576973652074616720646f6573206e6f74206d6174636820726567697374657260448201526a656420776973652074616760a81b6064820152608401610765565b60028101546005116116475760405162461bcd60e51b815260206004820152601e60248201527f4d6178696d756d206465706f73697420616d6f756e74207265616368656400006044820152606401610765565b6006548510156116b85760405162461bcd60e51b815260206004820152603660248201527f4465706f73697420616d6f756e74206d757374206265206772656174657220746044820152751a185b881b5a5b8819195c1bdcda5d08185b5bdd5b9d60521b6064820152608401610765565b600084116117165760405162461bcd60e51b815260206004820152602560248201527f5265636569766520616d6f756e74206d75737420626520677265617465722074604482015264068616e20360dc1b6064820152608401610765565b60008461172b670de0b6b3a7640000886140c2565b61173591906140ef565b600c8054919250600091908261174a8361401f565b9091555060028401805460018101825560009182526020918290200182905560408051610120810182523381528151601f8e018490048402810184019092528c8252929350828201918d908d908190840183828082843760009201829052509385525050506001600160a01b03881660208084019190915260408084018c9052606084018d9052608084018c905260a0840183905260c084018790528051838152918201905260e090920191905090526000828152600460209081526040909120825181546001600160a01b0319166001600160a01b0390911617815590820151600182019061183a9082614149565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e0820151600782015561010082015180516118af916008840191602090910190613836565b50506040516323b872dd60e01b8152336004820152306024820152604481018990527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691506323b872dd906064016020604051808303816000875af1158015611925573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119499190613f77565b50835160408051898152602081018590528a929184917f94c4b6f8843ea372709c89bc4a9ed85ef74ab10a68713ffdddc31716a76a6c95910160405180910390a450505050505050505050565b60008060006119a6868686612d47565b6040805160a08101825284546001600160a01b0390811682526001860154166020820152600285015491810191909152600384015460608201526004909301546080840152919450925090506119fc828261309d565b8260600151826006016000828254611a149190613fc2565b9091555050600154835160405163e0b490f760e01b81526001600160a01b039182166004820152429260039260009291169063e0b490f790602401602060405180830381865afa158015611a6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a909190613f5e565b815260200190815260200160002060010181905550611ab38360400151836131e6565b611abd818461335c565b505050505050565b611acd612a79565b66b1a2bc2ec50000811115611b2f5760405162461bcd60e51b815260206004820152602260248201527f4665652063616e6e6f742062652067726561746572207468616e206d61782066604482015261656560f01b6064820152608401610765565b600a8190556040518181527f44f48e1b871e6db1e909a7b253b054b7150a0b4ddf4d59b159c827d82e72567090602001610679565b6000818152600560209081526040808320815160a08101835281546001600160a01b03908116825260018301548116828601526002830154828501819052600384015460608401526004938401546080840152865291909352922081519192909116611c0a5760405162461bcd60e51b8152602060048201526015602482015274125b9d195b9d08191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606401610765565b80546001600160a01b03163314611c635760405162461bcd60e51b815260206004820152601c60248201527f43616c6c6572206d75737420626520746865206465706f7369746f72000000006044820152606401610765565b611c6d818461309d565b8160600151816006016000828254611c859190613fc2565b9091555050600154825160405163e0b490f760e01b81526001600160a01b039182166004820152429260039260009291169063e0b490f790602401602060405180830381865afa158015611cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d019190613f5e565b815260200190815260200160002060010181905550611d248260400151826131e6565b611d2e838361335c565b505050565b6000805b8251811015611e94576000838281518110611d5457611d54613fd5565b6020908102919091018101516000818152600490925260409091208054919250906001600160a01b03163314611dcc5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206d75737420626520746865206465706f7369746f72000000006044820152606401610765565b600080611dd884612b3e565b91509150611de68383612ce5565b808360050154611df69190613faf565b611e009087613faf565b955080836006016000828254611e169190613fc2565b9091555050825460058401546001600160a01b039091169085907fae1f357660ab777dcfd38c0ab6357834684ec26289ecfa07ec65dbf6c3c6431290611e5d908590613faf565b60405190815260200160405180910390a360006005840155611e7f84846131e6565b5050505080611e8d9061401f565b9050611d37565b5060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015611f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2e9190613f77565b611f2e612a79565b611f38600061353a565b565b606081516001600160401b03811115611f5557611f55613cdb565b604051908082528060200260200182016040528015611f8e57816020015b611f7b61380a565b815260200190600190039081611f735790505b50905060005b825181101561221c576000838281518110611fb157611fb1613fd5565b60209081029190910181015160008181526004835260408082208151610120810190925280546001600160a01b031682526001810180549496509294919390929184019190611fff90613feb565b80601f016020809104026020016040519081016040528092919081815260200182805461202b90613feb565b80156120785780601f1061204d57610100808354040283529160200191612078565b820191906000526020600020905b81548152906001019060200180831161205b57829003601f168201915b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820180548060200260200160405190810160405280929190818152602001828054801561213157602002820191906000526020600020905b81548152602001906001019080831161211d575b5050505050815250509050600061214783612b3e565b604080516080810182528681526001548651925163e0b490f760e01b81526001600160a01b039384166004820152939550909350602084019291169063e0b490f790602401602060405180830381865afa1580156121a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121cd9190613f5e565b8152602001838152602001828460a001516121e89190613faf565b8152508585815181106121fd576121fd613fd5565b6020026020010181905250505050806122159061401f565b9050611f94565b50919050565b61222a612a79565b806000036122845760405162461bcd60e51b815260206004820152602160248201527f4d6178206f6e2072616d7020616d6f756e742063616e6e6f74206265207a65726044820152606f60f81b6064820152608401610765565b60078190556040518181527fcab6b49ca21dd111cf4a55d507bbe89dd12d69216e28247060d4b2163ca41b3990602001610679565b6122c1613881565b6000828152600460209081526040918290208251610120810190935280546001600160a01b0316835260018101805491928401916122fe90613feb565b80601f016020809104026020016040519081016040528092919081815260200182805461232a90613feb565b80156123775780601f1061234c57610100808354040283529160200191612377565b820191906000526020600020905b81548152906001019060200180831161235a57829003601f168201915b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820180548060200260200160405190810160405280929190818152602001828054801561243057602002820191906000526020600020905b81548152602001906001019080831161241c575b5050505050815250509050919050565b600460205260009081526040902080546001820180546001600160a01b03909216929161246c90613feb565b80601f016020809104026020016040519081016040528092919081815260200182805461249890613feb565b80156124e55780601f106124ba576101008083540402835291602001916124e5565b820191906000526020600020905b8154815290600101906020018083116124c857829003601f168201915b5050506002840154600385015460048601546005870154600688015460079098015496976001600160a01b0390941696929550909350919088565b600061252b82610684565b92915050565b612539612a79565b6001600160a01b03811661259b5760405162461bcd60e51b8152602060048201526024808201527f46656520726563697069656e742063616e6e6f74206265207a65726f206164646044820152637265737360e01b6064820152608401610765565b600b80546001600160a01b0319166001600160a01b0383169081179091556040519081527f594ad6ee98bfc0c73e6d15fd4e762502f359e05d26907b7fa1ff82eb5e99f6e490602001610679565b6000818152600560209081526040808320815160a08101835281546001600160a01b039081168252600183015416938101939093526002810154918301919091526003810154606083015260040154608082018190529091036126865760405162461bcd60e51b8152602060048201526015602482015274125b9d195b9d08191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606401610765565b60015460405163e0b490f760e01b81523360048201526001600160a01b039091169063e0b490f790602401602060405180830381865afa1580156126ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126f29190613f5e565b600154825160405163e0b490f760e01b81526001600160a01b03918216600482015291169063e0b490f790602401602060405180830381865afa15801561273d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127619190613f5e565b146127ae5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206d75737420626520746865206f6e2d72616d706572000000006044820152606401610765565b60408082015160009081526004602052206127c9818461309d565b81606001518160050160008282546127e19190613faf565b909155505060608201516006820180546000906127ff908490613fc2565b9091555050505050565b60606000826001600160401b0381111561282557612825613cdb565b60405190808252806020026020018201604052801561289f57816020015b61288c60408051606080820183526000808352835160a0810185528181526020818101839052948101829052918201819052608082015290918201908152600060209091015290565b8152602001906001900390816128435790505b50905060005b838110156129f85760008585838181106128c1576128c1613fd5565b60209081029290920135600081815260058452604090819020815160a08101835281546001600160a01b0390811682526001830154169581019590955260028101548583015260038101546060808701919091526004909101546080860152815190810190915290935090508088888681811061294057612940613fd5565b60209081029290920135835250810183905260015483516040805163e0b490f760e01b81526001600160a01b03928316600482015293019291169063e0b490f790602401602060405180830381865afa1580156129a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c59190613f5e565b8152508484815181106129da576129da613fd5565b60200260200101819052505050806129f19061401f565b90506128a5565b509392505050565b612a08612a79565b6001600160a01b038116612a6d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610765565b612a768161353a565b50565b6000546001600160a01b03163314611f385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610765565b6040805160208101849052908101829052426060820152600090819060800160408051601f1981840301815291905280516020909101209050612b367f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000182614208565b949350505050565b60008181526004602090815260408083206008018054825181850281018501909352808352606094938493929190830182828015612b9b57602002820191906000526020600020905b815481526020019060010190808311612b87575b5050505050905080516001600160401b03811115612bbb57612bbb613cdb565b604051908082528060200260200182016040528015612be4578160200160208202803683370190505b50925060005b8151811015612cde57600060056000848481518110612c0b57612c0b613fd5565b6020908102919091018101518252818101929092526040908101600020815160a08101835281546001600160a01b039081168252600183015416938101939093526002810154918301919091526003810154606083015260040154608082018190526009549192504291612c7e91613faf565b1015612ccd57828281518110612c9657612c96613fd5565b6020026020010151858381518110612cb057612cb0613fd5565b60209081029190910101526060810151612cca9085613faf565b93505b50612cd78161401f565b9050612bea565b5050915091565b60005b8151811015611d2e576000801b828281518110612d0757612d07613fd5565b602002602001015114612d3757612d3783838381518110612d2a57612d2a613fd5565b602002602001015161309d565b612d408161401f565b9050612ce8565b610120830135600081815260056020526040812080549092906001600160a01b03163314612db75760405162461bcd60e51b815260206004820152601c60248201527f43616c6c6572206d75737420626520746865206f6e2d72616d706572000000006044820152606401610765565b6002808401546000908152600460205260408082209254815180830190925292945090918291829182916001600160a01b039091169063f20333c19080612dfd8e61428b565b81526020018c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505091525060028901546040516001600160e01b031960e085901b168152612e6a92916001600160a01b03169060040161440b565b6080604051808303816000875af1158015612e89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ead9190614563565b935093509350935085600401548114612efe5760405162461bcd60e51b815260206004820152601360248201527215dc9bdb99c818dd5c9c995b98de481cd95b9d606a1b6044820152606401610765565b8287600401541115612f5d5760405162461bcd60e51b815260206004820152602260248201527f496e74656e7420776173206e6f742063726561746564206265666f72652073656044820152611b9960f21b6064820152608401610765565b6001548654604051630f6a21fd60e31b81526001600160a01b03918216600482015284929190911690637b510fe890602401606060405180830381865afa158015612fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd09190614038565b60200151146130215760405162461bcd60e51b815260206004820152601b60248201527f4f666672616d70657220696420646f6573206e6f74206d6174636800000000006044820152606401610765565b8560070154670de0b6b3a7640000886003015461303e91906140c2565b61304891906140ef565b8410156130905760405162461bcd60e51b81526020600482015260166024820152750a0c2f2dacadce840eec2e640dcdee840cadcdeeaced60531b6044820152606401610765565b5050505093509350939050565b6000818152600560209081526040808320815160a08101835281546001600160a01b03908116808352600180850154831696840196909652600284015483860152600380850154606085015260049485015460808501529554945163e0b490f760e01b815293840152909492169063e0b490f790602401602060405180830381865afa158015613131573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131559190613f5e565b8152602080820192909252604090810160009081208190558481526005909252812080546001600160a01b0319908116825560018201805490911690556002810182905560038101829055600401556131b1600884018361358a565b604080820151905183907fe8a865b4bab023c399cbd1f2cdd0df2199beb6e5012a4bd2d7691cf7e4199d5a90600090a3505050565b6000816005015482600601546131fc9190613faf565b905080600003611d2e57600154825460405163e0b490f760e01b81526001600160a01b0391821660048201526132a2928692600392600092919091169063e0b490f790602401602060405180830381865afa15801561325f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132839190613f5e565b81526020019081526020016000206002016136b290919063ffffffff16565b8154604080518581526001600160a01b0390921660208301527f8ac07cc6e38c6222dd0309c80353c1962354bacf222b825d7401cc80e93ff3cc910160405180910390a1600083815260046020526040812080546001600160a01b03191681559061331060018301826138e2565b6002820180546001600160a01b03191690556000600383018190556004830181905560058301819055600683018190556007830181905561335590600884019061391c565b5050505050565b6000600a5460001461342857670de0b6b3a7640000600a54836060015161338391906140c2565b61338d91906140ef565b600b5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015613402573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134269190613f77565b505b600081836060015161343a9190613fc2565b602084015160405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156134b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d59190613f77565b50825160408085015160208087015183516001600160a01b03918216815291820186905292810186905291909216919086907ffa03438194e61c243c6bb5349f1e1dc674431b86f119b5e3b2b327bc43446bce9060600160405180910390a450505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806135e6848054806020026020016040519081016040528092919081815260200182805480156135db57602002820191906000526020600020905b8154815260200190600101908083116135c7575b505050505084613757565b915091508061362f5760405162461bcd60e51b8152602060048201526015602482015274313cba32b99999103737ba1034b71030b93930bc9760591b6044820152606401610765565b835460009061364090600190613fc2565b90508083146136855784818154811061365b5761365b613fd5565b906000526020600020015485848154811061367857613678613fd5565b6000918252602090912001555b8480548061369557613695614599565b600190038181906000526020600020016000905590555050505050565b60008061370e8480548060200260200160405190810160405280929190818152602001828054801561370357602002820191906000526020600020905b8154815260200190600101908083116136ef575b5050505050846137ba565b915091508061362f5760405162461bcd60e51b81526020600482015260156024820152743ab4b73a191a9b103737ba1034b71030b93930bc9760591b6044820152606401610765565b81516000908190815b818110156137a7578486828151811061377b5761377b613fd5565b602002602001015103613795579250600191506137b39050565b8061379f8161401f565b915050613760565b50600019600092509250505b9250929050565b81516000908190815b818110156137a757848682815181106137de576137de613fd5565b6020026020010151036137f8579250600191506137b39050565b806138028161401f565b9150506137c3565b6040805160808101825260008082526020820152908101613829613881565b8152602001600081525090565b828054828255906000526020600020908101928215613871579160200282015b82811115613871578251825591602001919060010190613856565b5061387d929150613936565b5090565b60405180610120016040528060006001600160a01b031681526020016060815260200160006001600160a01b031681526020016000815260200160008019168152602001600081526020016000815260200160008152602001606081525090565b5080546138ee90613feb565b6000825580601f106138fe575050565b601f016020900490600052602060002090810190612a769190613936565b5080546000825590600052602060002090810190612a7691905b5b8082111561387d5760008155600101613937565b6001600160a01b0381168114612a7657600080fd5b60006020828403121561397257600080fd5b813561397d8161394b565b9392505050565b60006020828403121561399657600080fd5b5035919050565b6000806000606084860312156139b257600080fd5b833592506020840135915060408401356139cb8161394b565b809150509250925092565b600080604083850312156139e957600080fd5b82356139f48161394b565b91506020830135613a048161394b565b809150509250929050565b6000815180845260005b81811015613a3557602081850181015186830182015201613a19565b506000602082860101526020601f19601f83011685010191505092915050565b600081518084526020808501945080840160005b83811015613a8557815187529582019590820190600101613a69565b509495945050505050565b80516001600160a01b0316825260006101206020830151816020860152613ab982860182613a0f565b9150506040830151613ad660408601826001600160a01b03169052565b50606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e083015160e08501526101008084015185830382870152613b218382613a55565b9695505050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015613ba957603f1989840301855281516080815185528882015189860152878201518189870152613b8882870182613a90565b60609384015196909301959095525094870194925090860190600101613b52565b509098975050505050505050565b60008083601f840112613bc957600080fd5b5081356001600160401b03811115613be057600080fd5b6020830191508360208285010111156137b357600080fd5b60008060008060008060a08789031215613c1157600080fd5b86356001600160401b03811115613c2757600080fd5b613c3389828a01613bb7565b9097509550506020870135935060408701359250606087013591506080870135613c5c8161394b565b809150509295509295509295565b600080600060408486031215613c7f57600080fd5b83356001600160401b0380821115613c9657600080fd5b908501906101408288031215613cab57600080fd5b90935060208501359080821115613cc157600080fd5b50613cce86828701613bb7565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405161014081016001600160401b0381118282101715613d1457613d14613cdb565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613d4257613d42613cdb565b604052919050565b60006020808385031215613d5d57600080fd5b82356001600160401b0380821115613d7457600080fd5b818501915085601f830112613d8857600080fd5b813581811115613d9a57613d9a613cdb565b8060051b9150613dab848301613d1a565b8181529183018401918481019088841115613dc557600080fd5b938501935b83851015613de357843582529385019390850190613dca565b98975050505050505050565b60208152600061397d6020830184613a90565b6001600160a01b03898116825261010060208301819052600091613e288483018c613a0f565b9916604084015250506060810195909552608085019390935260a084019190915260c083015260e09091015292915050565b60008060208385031215613e6d57600080fd5b82356001600160401b0380821115613e8457600080fd5b818501915085601f830112613e9857600080fd5b813581811115613ea757600080fd5b8660208260051b8501011115613ebc57600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b82811015613f51578151805185528681015180516001600160a01b039081168988015281890151168787015286810151606080880191909152810151608080880191909152015160a086015285015160c085015260e09093019290850190600101613eeb565b5091979650505050505050565b600060208284031215613f7057600080fd5b5051919050565b600060208284031215613f8957600080fd5b8151801515811461397d57600080fd5b634e487b7160e01b600052601160045260246000fd5b8082018082111561252b5761252b613f99565b8181038181111561252b5761252b613f99565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680613fff57607f821691505b60208210810361221c57634e487b7160e01b600052602260045260246000fd5b60006001820161403157614031613f99565b5060010190565b60006060828403121561404a57600080fd5b604051606081018181106001600160401b038211171561406c5761406c613cdb565b80604052508251815260208301516020820152604083015160408201528091505092915050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b808202811582820484141761252b5761252b613f99565b634e487b7160e01b600052601260045260246000fd5b6000826140fe576140fe6140d9565b500490565b601f821115611d2e57600081815260208120601f850160051c8101602086101561412a5750805b601f850160051c820191505b81811015611abd57828155600101614136565b81516001600160401b0381111561416257614162613cdb565b614176816141708454613feb565b84614103565b602080601f8311600181146141ab57600084156141935750858301515b600019600386901b1c1916600185901b178555611abd565b600085815260208120601f198616915b828110156141da578886015182559484019460019091019084016141bb565b50858210156141f85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600082614217576142176140d9565b500690565b600082601f83011261422d57600080fd5b81356001600160401b0381111561424657614246613cdb565b614259601f8201601f1916602001613d1a565b81815284602083860101111561426e57600080fd5b816020850160208301376000918101602001919091529392505050565b6000610140823603121561429e57600080fd5b6142a6613cf1565b82356001600160401b03808211156142bd57600080fd5b6142c93683870161421c565b835260208501359150808211156142df57600080fd5b6142eb3683870161421c565b6020840152604085013591508082111561430457600080fd5b6143103683870161421c565b6040840152606085013591508082111561432957600080fd5b6143353683870161421c565b6060840152608085013591508082111561434e57600080fd5b61435a3683870161421c565b608084015260a085013591508082111561437357600080fd5b61437f3683870161421c565b60a084015260c085013591508082111561439857600080fd5b6143a43683870161421c565b60c084015260e08501359150808211156143bd57600080fd5b6143c93683870161421c565b60e0840152610100915081850135818111156143e457600080fd5b6143f03682880161421c565b92840192909252505061012092830135928101929092525090565b604081526000835160408084015280516101408060808601526144326101c0860183613a0f565b91506020830151607f19808785030160a08801526144508483613a0f565b935060408501519150808785030160c088015261446d8483613a0f565b935060608501519150808785030160e088015261448a8483613a0f565b9350608085015191506101008188860301818901526144a98584613a0f565b945060a086015192506101208289870301818a01526144c88685613a0f565b955060c087015193508289870301858a01526144e48685613a0f565b955060e0870151945082898703016101608a01526145028686613a0f565b955081870151945082898703016101808a015261451f8686613a0f565b9601516101a0890152505050506020860151848303603f1901606086015291905061454a8183613a0f565b9250505061397d60208301846001600160a01b03169052565b6000806000806080858703121561457957600080fd5b505082516020840151604085015160609095015191969095509092509050565b634e487b7160e01b600052603160045260246000fdfea264697066735822122004ea0f66a7be18f0d38eef6096cdd835afaebe0d26328cd92d300376f8d8d6b564736f6c63430008120033", "devdoc": { "kind": "dev", "methods": { @@ -1461,23 +1461,23 @@ "type": "t_address" }, { - "astId": 19137, + "astId": 4410, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "accountRegistry", "offset": 0, "slot": "1", - "type": "t_contract(IWiseAccountRegistry)21116" + "type": "t_contract(IWiseAccountRegistry)6364" }, { - "astId": 19140, + "astId": 4413, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "sendProcessor", "offset": 0, "slot": "2", - "type": "t_contract(IWiseSendProcessor)21192" + "type": "t_contract(IWiseSendProcessor)6438" }, { - "astId": 19142, + "astId": 4415, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "isInitialized", "offset": 20, @@ -1485,31 +1485,31 @@ "type": "t_bool" }, { - "astId": 19147, + "astId": 4420, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "globalAccount", "offset": 0, "slot": "3", - "type": "t_mapping(t_bytes32,t_struct(GlobalAccountInfo)19106_storage)" + "type": "t_mapping(t_bytes32,t_struct(GlobalAccountInfo)4379_storage)" }, { - "astId": 19152, + "astId": 4425, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "deposits", "offset": 0, "slot": "4", - "type": "t_mapping(t_uint256,t_struct(Deposit)19069_storage)" + "type": "t_mapping(t_uint256,t_struct(Deposit)4342_storage)" }, { - "astId": 19157, + "astId": 4430, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "intents", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(Intent)19090_storage)" + "type": "t_mapping(t_bytes32,t_struct(Intent)4363_storage)" }, { - "astId": 19159, + "astId": 4432, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "minDepositAmount", "offset": 0, @@ -1517,7 +1517,7 @@ "type": "t_uint256" }, { - "astId": 19161, + "astId": 4434, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "maxOnRampAmount", "offset": 0, @@ -1525,7 +1525,7 @@ "type": "t_uint256" }, { - "astId": 19163, + "astId": 4436, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "onRampCooldownPeriod", "offset": 0, @@ -1533,7 +1533,7 @@ "type": "t_uint256" }, { - "astId": 19165, + "astId": 4438, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "intentExpirationPeriod", "offset": 0, @@ -1541,7 +1541,7 @@ "type": "t_uint256" }, { - "astId": 19167, + "astId": 4440, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "sustainabilityFee", "offset": 0, @@ -1549,7 +1549,7 @@ "type": "t_uint256" }, { - "astId": 19169, + "astId": 4442, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "sustainabilityFeeRecipient", "offset": 0, @@ -1557,7 +1557,7 @@ "type": "t_address" }, { - "astId": 19171, + "astId": 4444, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "depositCounter", "offset": 0, @@ -1593,48 +1593,48 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_contract(IWiseAccountRegistry)21116": { + "t_contract(IWiseAccountRegistry)6364": { "encoding": "inplace", "label": "contract IWiseAccountRegistry", "numberOfBytes": "20" }, - "t_contract(IWiseSendProcessor)21192": { + "t_contract(IWiseSendProcessor)6438": { "encoding": "inplace", "label": "contract IWiseSendProcessor", "numberOfBytes": "20" }, - "t_mapping(t_bytes32,t_struct(GlobalAccountInfo)19106_storage)": { + "t_mapping(t_bytes32,t_struct(GlobalAccountInfo)4379_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct WiseRamp.GlobalAccountInfo)", "numberOfBytes": "32", - "value": "t_struct(GlobalAccountInfo)19106_storage" + "value": "t_struct(GlobalAccountInfo)4379_storage" }, - "t_mapping(t_bytes32,t_struct(Intent)19090_storage)": { + "t_mapping(t_bytes32,t_struct(Intent)4363_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct WiseRamp.Intent)", "numberOfBytes": "32", - "value": "t_struct(Intent)19090_storage" + "value": "t_struct(Intent)4363_storage" }, - "t_mapping(t_uint256,t_struct(Deposit)19069_storage)": { + "t_mapping(t_uint256,t_struct(Deposit)4342_storage)": { "encoding": "mapping", "key": "t_uint256", "label": "mapping(uint256 => struct WiseRamp.Deposit)", "numberOfBytes": "32", - "value": "t_struct(Deposit)19069_storage" + "value": "t_struct(Deposit)4342_storage" }, "t_string_storage": { "encoding": "bytes", "label": "string", "numberOfBytes": "32" }, - "t_struct(Deposit)19069_storage": { + "t_struct(Deposit)4342_storage": { "encoding": "inplace", "label": "struct WiseRamp.Deposit", "members": [ { - "astId": 19051, + "astId": 4324, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "depositor", "offset": 0, @@ -1642,7 +1642,7 @@ "type": "t_address" }, { - "astId": 19053, + "astId": 4326, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "wiseTag", "offset": 0, @@ -1650,7 +1650,7 @@ "type": "t_string_storage" }, { - "astId": 19055, + "astId": 4328, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "verifierSigningKey", "offset": 0, @@ -1658,7 +1658,7 @@ "type": "t_address" }, { - "astId": 19057, + "astId": 4330, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "depositAmount", "offset": 0, @@ -1666,7 +1666,7 @@ "type": "t_uint256" }, { - "astId": 19059, + "astId": 4332, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "receiveCurrencyId", "offset": 0, @@ -1674,7 +1674,7 @@ "type": "t_bytes32" }, { - "astId": 19061, + "astId": 4334, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "remainingDeposits", "offset": 0, @@ -1682,7 +1682,7 @@ "type": "t_uint256" }, { - "astId": 19063, + "astId": 4336, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "outstandingIntentAmount", "offset": 0, @@ -1690,7 +1690,7 @@ "type": "t_uint256" }, { - "astId": 19065, + "astId": 4338, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "conversionRate", "offset": 0, @@ -1698,7 +1698,7 @@ "type": "t_uint256" }, { - "astId": 19068, + "astId": 4341, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "intentHashes", "offset": 0, @@ -1708,12 +1708,12 @@ ], "numberOfBytes": "288" }, - "t_struct(GlobalAccountInfo)19106_storage": { + "t_struct(GlobalAccountInfo)4379_storage": { "encoding": "inplace", "label": "struct WiseRamp.GlobalAccountInfo", "members": [ { - "astId": 19100, + "astId": 4373, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "currentIntentHash", "offset": 0, @@ -1721,7 +1721,7 @@ "type": "t_bytes32" }, { - "astId": 19102, + "astId": 4375, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "lastOnrampTimestamp", "offset": 0, @@ -1729,7 +1729,7 @@ "type": "t_uint256" }, { - "astId": 19105, + "astId": 4378, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "deposits", "offset": 0, @@ -1739,12 +1739,12 @@ ], "numberOfBytes": "96" }, - "t_struct(Intent)19090_storage": { + "t_struct(Intent)4363_storage": { "encoding": "inplace", "label": "struct WiseRamp.Intent", "members": [ { - "astId": 19081, + "astId": 4354, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "onRamper", "offset": 0, @@ -1752,7 +1752,7 @@ "type": "t_address" }, { - "astId": 19083, + "astId": 4356, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "to", "offset": 0, @@ -1760,7 +1760,7 @@ "type": "t_address" }, { - "astId": 19085, + "astId": 4358, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "deposit", "offset": 0, @@ -1768,7 +1768,7 @@ "type": "t_uint256" }, { - "astId": 19087, + "astId": 4360, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "amount", "offset": 0, @@ -1776,7 +1776,7 @@ "type": "t_uint256" }, { - "astId": 19089, + "astId": 4362, "contract": "contracts/ramps/wise/WiseRamp.sol:WiseRamp", "label": "intentTimestamp", "offset": 0, diff --git a/contracts/deployments/sepolia/WiseSendProcessor.json b/contracts/deployments/sepolia/WiseSendProcessor.json index 9155caf34..31af99455 100644 --- a/contracts/deployments/sepolia/WiseSendProcessor.json +++ b/contracts/deployments/sepolia/WiseSendProcessor.json @@ -1,5 +1,5 @@ { - "address": "0xFb08d7be04cCD00dF074bBa1D28D4B9887a8D5e6", + "address": "0x9ECa55F6dFd743b078a3b987CeB79B8Fc3319dF1", "abi": [ { "inputs": [ @@ -210,11 +210,6 @@ "name": "offRamperId", "type": "bytes32" }, - { - "internalType": "bytes32", - "name": "onRamperId", - "type": "bytes32" - }, { "internalType": "bytes32", "name": "currencyId", @@ -284,49 +279,49 @@ "type": "function" } ], - "transactionHash": "0x1e560757ca1c6a45f79cbbef8062201be73d41aa45237142123230587d8c3e1b", + "transactionHash": "0xfc8407f994c23cbdc57f32314233b29bea9958b29bfc3e19c1663cb10ceea2a3", "receipt": { "to": null, "from": "0x4e39cF8578698131c57404e8bc3eEC820EDa51d8", - "contractAddress": "0xFb08d7be04cCD00dF074bBa1D28D4B9887a8D5e6", - "transactionIndex": 110, - "gasUsed": "1699352", - "logsBloom": "0x00000000000000000000000000000000000040000000000000800000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000020000000000100000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xb8586ec5fa6208f9c2cc2ffb8c9b4de2f6c448f190b6f8a6e7ea2544c3444774", - "transactionHash": "0x1e560757ca1c6a45f79cbbef8062201be73d41aa45237142123230587d8c3e1b", + "contractAddress": "0x9ECa55F6dFd743b078a3b987CeB79B8Fc3319dF1", + "transactionIndex": 5, + "gasUsed": "1690509", + "logsBloom": "0x00000000000000000000000000080000000000000000000000800000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000100000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000080000000000000000000000000000000000000", + "blockHash": "0xbe89e2ab4ededf474d1c406607a4bfdbf49cae24b044f5816d9de657e256f4e6", + "transactionHash": "0xfc8407f994c23cbdc57f32314233b29bea9958b29bfc3e19c1663cb10ceea2a3", "logs": [ { - "transactionIndex": 110, - "blockNumber": 5574199, - "transactionHash": "0x1e560757ca1c6a45f79cbbef8062201be73d41aa45237142123230587d8c3e1b", - "address": "0xFb08d7be04cCD00dF074bBa1D28D4B9887a8D5e6", + "transactionIndex": 5, + "blockNumber": 5635197, + "transactionHash": "0xfc8407f994c23cbdc57f32314233b29bea9958b29bfc3e19c1663cb10ceea2a3", + "address": "0x9ECa55F6dFd743b078a3b987CeB79B8Fc3319dF1", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000004e39cf8578698131c57404e8bc3eec820eda51d8" ], "data": "0x", - "logIndex": 1151, - "blockHash": "0xb8586ec5fa6208f9c2cc2ffb8c9b4de2f6c448f190b6f8a6e7ea2544c3444774" + "logIndex": 8, + "blockHash": "0xbe89e2ab4ededf474d1c406607a4bfdbf49cae24b044f5816d9de657e256f4e6" } ], - "blockNumber": 5574199, - "cumulativeGasUsed": "23717748", + "blockNumber": 5635197, + "cumulativeGasUsed": "10307740", "status": 1, "byzantium": true }, "args": [ - "0xfb5294d3E7EDE246dcD933b064ADcBd2e2624059", + "0x96805415F53A166d6CC16B3CAA9EE085E28511b9", "0xAf0196f22a1383B779E3f833AD35BFf38722c8AD", "30", "GET https://wise.com/gateway/v3/profiles/*/transfers", "wise.com" ], "numDeployments": 1, - "solcInputHash": "6e4c0155cf194d54974389502ced73c2", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_ramp\",\"type\":\"address\"},{\"internalType\":\"contract INullifierRegistry\",\"name\":\"_nullifierRegistry\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_host\",\"type\":\"string\"}],\"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\"},{\"inputs\":[],\"name\":\"PAYMENT_STATUS\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"endpoint\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"host\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nullifierRegistry\",\"outputs\":[{\"internalType\":\"contract INullifierRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"transferId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"senderId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"recipientId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"amount\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"currencyId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"status\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"timestamp\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"intentHash\",\"type\":\"uint256\"}],\"internalType\":\"struct IWiseSendProcessor.SendData\",\"name\":\"public_values\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"internalType\":\"struct IWiseSendProcessor.SendProof\",\"name\":\"_proof\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"}],\"name\":\"processProof\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"offRamperId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"onRamperId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"currencyId\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ramp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"}],\"name\":\"setTimestampBuffer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timestampBuffer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setTimestampBuffer(uint256)\":{\"params\":{\"_timestampBuffer\":\"The timestamp buffer for validated TLS calls\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"setTimestampBuffer(uint256)\":{\"notice\":\"ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2 timestamps.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ramps/wise/WiseSendProcessor.sol\":\"WiseSendProcessor\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"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/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/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"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\"},\"contracts/lib/StringConversionUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\n// Building on zk-email's StringUtils library we add the ability to handle decimals when\\n// converting from string to Uint\\nlibrary StringConversionUtils {\\n \\n /**\\n * @notice Function that parses numbers returned as strings including floating point numbers. Returned floating point\\n * numbers are to have the desired amount of decimal specified. If the stringified version of the floating point\\n * number has more decimal places than desired then the function will revert in order to be maximally safe. If\\n * the returned number has multiple floating points then the function will revert.\\n *\\n * Examples: _s = \\\"12.34\\\", _expectedDecimals = 6 => 12340000\\n * _s = \\\"12.34\\\", _expectedDecimals = 2 => 1234\\n * _s = \\\"12.34\\\", _expectedDecimals = 1 => REVERT (we never want loss of precision only addition)\\n * _s = \\\"12.34.56\\\", _expectedDecimals = 6 => REVERT (Invalid number)\\n *\\n * @param _s String being processed\\n * @param _desiredDecimals Desired amount of decimal places\\n */\\n function stringToUint(string memory _s, uint256 _desiredDecimals) internal pure returns (uint256) {\\n return stringToUint(_s, 0x2E, _desiredDecimals);\\n }\\n\\n function stringToUint(\\n string memory _s,\\n bytes1 _decimalCharacter,\\n uint256 _desiredDecimals\\n )\\n internal\\n pure\\n returns (uint256)\\n {\\n bytes memory b = bytes(_s);\\n\\n uint256 result = 0;\\n uint256 decimalPlaces = 0;\\n\\n bool decimals = false;\\n for (uint256 i = 0; i < b.length; i++) {\\n if (b[i] >= 0x30 && b[i] <= 0x39) {\\n result = result * 10 + (uint256(uint8(b[i])) - 48);\\n }\\n\\n if (decimals) {\\n decimalPlaces++;\\n }\\n\\n if (b[i] == _decimalCharacter) {\\n require(decimals == false, \\\"String has multiple decimals\\\");\\n decimals = true;\\n }\\n }\\n\\n require(decimalPlaces <= _desiredDecimals, \\\"String has too many decimal places\\\");\\n return result * (10 ** (_desiredDecimals - decimalPlaces));\\n }\\n\\n /**\\n * @notice Function that returns a substring from _startIndex to _endIndex (non-inclusive).\\n *\\n * @param _str String being processed\\n * @param _startIndex Index to start parsing from\\n * @param _endIndex Index to stop parsing at (index not included in result)\\n */\\n function substring(string memory _str, uint _startIndex, uint _endIndex) internal pure returns (string memory ) {\\n bytes memory strBytes = bytes(_str);\\n bytes memory result = new bytes(_endIndex-_startIndex);\\n for(uint i = _startIndex; i < _endIndex; i++) {\\n result[i-_startIndex] = strBytes[i];\\n }\\n return string(result);\\n }\\n\\n function replaceString(\\n string memory _str,\\n string memory _lookupValue,\\n string memory _replaceValue\\n )\\n internal\\n pure\\n returns (string memory)\\n {\\n bytes memory strBytes = bytes(_str);\\n bytes memory lookupBytes = bytes(_lookupValue);\\n\\n uint256 lookupIndex = indexOf(_str, _lookupValue);\\n if (lookupIndex == type(uint256).max) {\\n return _str;\\n }\\n\\n // Split the original string into two parts: before and after the keyword\\n string memory beforeKeyword = substring(_str, 0, lookupIndex);\\n string memory afterKeyword = substring(_str, lookupIndex + lookupBytes.length, strBytes.length);\\n \\n return string.concat(beforeKeyword, _replaceValue, afterKeyword);\\n }\\n\\n function indexOf(string memory str, string memory substr) internal pure returns (uint) {\\n bytes memory strBytes = bytes(str);\\n bytes memory substrBytes = bytes(substr);\\n \\n if (strBytes.length < substrBytes.length) return type(uint256).max;\\n \\n for (uint i = 0; i <= strBytes.length - substrBytes.length; i++) {\\n bool found = true;\\n for (uint j = 0; j < substrBytes.length; j++) {\\n if (strBytes[i + j] != substrBytes[j]) {\\n found = false;\\n break;\\n }\\n }\\n if (found) return i;\\n }\\n \\n return type(uint256).max;\\n }\\n\\n function stringComparison(string memory _a, string memory _b) internal pure returns (bool) {\\n return (keccak256(abi.encodePacked(_a)) == keccak256(abi.encodePacked(_b)));\\n }\\n}\\n\",\"keccak256\":\"0xfcdfb3c2c8d5a6b7f480f827049782a70fb98f8b3838dcad0e0bb95237b94a0c\",\"license\":\"MIT\"},\"contracts/processors/TLSBaseProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { ECDSA } from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { SignatureChecker } from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\n\\nimport { INullifierRegistry } from \\\"./nullifierRegistries/INullifierRegistry.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract TLSBaseProcessor is Ownable {\\n\\n using SignatureChecker for address;\\n using ECDSA for bytes32;\\n\\n /* ============ Modifiers ============ */\\n modifier onlyRamp() {\\n require(msg.sender == ramp, \\\"Only Ramp can call this function\\\");\\n _;\\n }\\n\\n /* ============ State Variables ============ */\\n address public immutable ramp;\\n string public endpoint;\\n string public host;\\n\\n INullifierRegistry public nullifierRegistry;\\n uint256 public timestampBuffer;\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _ramp,\\n INullifierRegistry _nullifierRegistry,\\n uint256 _timestampBuffer,\\n string memory _endpoint,\\n string memory _host\\n )\\n Ownable()\\n {\\n ramp = _ramp;\\n endpoint = _endpoint;\\n host = _host;\\n\\n nullifierRegistry = _nullifierRegistry;\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ External Functions ============ */\\n\\n /**\\n * @notice ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds\\n * that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2\\n * timestamps.\\n *\\n * @param _timestampBuffer The timestamp buffer for validated TLS calls\\n */\\n function setTimestampBuffer(uint256 _timestampBuffer) external onlyOwner {\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ Internal Functions ============ */\\n\\n function _validateTLSEndpoint(\\n string memory _expectedEndpoint,\\n string memory _passedEndpoint\\n )\\n internal\\n pure\\n {\\n require(\\n keccak256(abi.encode(_expectedEndpoint)) == keccak256(abi.encode(_passedEndpoint)),\\n \\\"Endpoint does not match expected\\\"\\n );\\n }\\n\\n function _validateTLSHost(\\n string memory _expectedHost,\\n string memory _passedHost\\n )\\n internal\\n pure\\n {\\n require(\\n keccak256(abi.encode(_expectedHost)) == keccak256(abi.encode(_passedHost)),\\n \\\"Host does not match expected\\\"\\n );\\n }\\n\\n function _validateAndAddNullifier(bytes32 _nullifier) internal {\\n require(!nullifierRegistry.isNullified(_nullifier), \\\"Nullifier has already been used\\\");\\n nullifierRegistry.addNullifier(_nullifier);\\n }\\n\\n function _isValidVerifierSignature(\\n bytes memory _message,\\n bytes memory _signature,\\n address _verifier\\n )\\n internal\\n view\\n returns(bool)\\n {\\n bytes32 verifierPayload = keccak256(_message).toEthSignedMessageHash();\\n\\n return _verifier.isValidSignatureNow(verifierPayload, _signature);\\n }\\n}\\n\",\"keccak256\":\"0xbbdb8f203288645916ad04ee65625fae570ed091fbf243a706df7991b29ffe61\",\"license\":\"MIT\"},\"contracts/processors/keyHashAdapters/IKeyHashAdapterV2.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IKeyHashAdapterV2 {\\n function addMailServerKeyHash(bytes32 _mailserverKeyHash) external;\\n function removeMailServerKeyHash(bytes32 _mailserverKeyHash) external;\\n function getMailServerKeyHashes() external view returns (bytes32[] memory);\\n function isMailServerKeyHash(bytes32 _mailserverKeyHash) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xc849f2dc34e4463550b8e0a16541bde429cb1adf43776b2c4179e9d4e4e656a2\",\"license\":\"MIT\"},\"contracts/processors/nullifierRegistries/INullifierRegistry.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface INullifierRegistry {\\n function addNullifier(bytes32 _nullifier) external;\\n function isNullified(bytes32 _nullifier) external view returns(bool);\\n}\\n\",\"keccak256\":\"0x107164bc9a320938b513305878163b7fa884da4cdae58d0c8e81bfbb00c97c5e\",\"license\":\"MIT\"},\"contracts/ramps/wise/WiseSendProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { ECDSA } from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport { SignatureChecker } from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\n\\nimport { IKeyHashAdapterV2 } from \\\"../../processors/keyHashAdapters/IKeyHashAdapterV2.sol\\\";\\nimport { INullifierRegistry } from \\\"../../processors/nullifierRegistries/INullifierRegistry.sol\\\";\\nimport { IWiseSendProcessor } from \\\"./interfaces/IWiseSendProcessor.sol\\\";\\nimport { StringConversionUtils } from \\\"../../lib/StringConversionUtils.sol\\\";\\nimport { TLSBaseProcessor } from \\\"../../processors/TLSBaseProcessor.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract WiseSendProcessor is IWiseSendProcessor, TLSBaseProcessor {\\n\\n using ECDSA for bytes32;\\n using SignatureChecker for address;\\n using StringConversionUtils for string;\\n\\n /* ============ Constants ============ */\\n bytes32 public constant PAYMENT_STATUS = keccak256(abi.encodePacked(\\\"OUTGOING_PAYMENT_SENT\\\"));\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _ramp,\\n INullifierRegistry _nullifierRegistry,\\n uint256 _timestampBuffer,\\n string memory _endpoint,\\n string memory _host\\n )\\n TLSBaseProcessor(\\n _ramp,\\n _nullifierRegistry,\\n _timestampBuffer,\\n _endpoint,\\n _host\\n )\\n {}\\n \\n /* ============ External Functions ============ */\\n function processProof(\\n IWiseSendProcessor.SendProof calldata _proof,\\n address _verifierSigningKey\\n )\\n public\\n override\\n onlyRamp\\n returns(\\n uint256 amount,\\n uint256 timestamp,\\n bytes32 offRamperId,\\n bytes32 onRamperId,\\n bytes32 currencyId\\n )\\n {\\n _validateProof(_verifierSigningKey, _proof.public_values, _proof.proof);\\n\\n _validateTLSEndpoint(\\n endpoint.replaceString(\\\"*\\\", _proof.public_values.senderId),\\n _proof.public_values.endpoint\\n );\\n _validateTLSHost(host, _proof.public_values.host);\\n \\n // Validate status\\n require(\\n keccak256(abi.encodePacked(_proof.public_values.status)) == PAYMENT_STATUS,\\n \\\"Payment status not confirmed as sent\\\"\\n );\\n _validateAndAddNullifier(keccak256(abi.encodePacked(\\\"Wise\\\", _proof.public_values.transferId)));\\n\\n amount = _proof.public_values.amount.stringToUint(6);\\n\\n // Add the buffer to build in flexibility with L2 timestamps\\n timestamp = _proof.public_values.timestamp.stringToUint(0) / 1000 + timestampBuffer;\\n\\n offRamperId = bytes32(_proof.public_values.recipientId.stringToUint(0));\\n onRamperId = bytes32(_proof.public_values.senderId.stringToUint(0));\\n currencyId = keccak256(abi.encodePacked(_proof.public_values.currencyId));\\n }\\n\\n /* ============ View Functions ============ */\\n\\n function verifyProof(\\n address _verifierSigningKey,\\n IWiseSendProcessor.SendData memory _publicValues, \\n bytes memory _proof\\n )\\n internal\\n view\\n returns(bool)\\n { \\n bytes memory encodedMessage = abi.encode(\\n _publicValues.endpoint,\\n _publicValues.host,\\n _publicValues.transferId,\\n _publicValues.senderId,\\n _publicValues.recipientId,\\n _publicValues.amount,\\n _publicValues.currencyId,\\n _publicValues.status,\\n _publicValues.timestamp,\\n _publicValues.intentHash\\n );\\n return _isValidVerifierSignature(encodedMessage, _proof, _verifierSigningKey);\\n }\\n\\n /* ============ Internal Functions ============ */\\n\\n function _validateProof(\\n address _verifierSigningKey,\\n IWiseSendProcessor.SendData memory _publicValues, \\n bytes memory _proof\\n )\\n internal\\n view\\n { \\n require(\\n verifyProof(_verifierSigningKey, _publicValues, _proof),\\n \\\"Invalid signature from verifier\\\"\\n );\\n }\\n}\\n\",\"keccak256\":\"0x1e8adbc06a99370b2b215a4960738a34a3216a65eece79eb9a847de6768d287c\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseSendProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseSendProcessor {\\n\\n struct SendData {\\n string endpoint;\\n string host;\\n string transferId;\\n string senderId;\\n string recipientId;\\n string amount;\\n string currencyId;\\n string status;\\n string timestamp;\\n uint256 intentHash;\\n }\\n\\n struct SendProof {\\n SendData public_values;\\n bytes proof;\\n }\\n\\n function processProof(\\n SendProof calldata _proof,\\n address _verifierSigningKey\\n )\\n external\\n returns(uint256, uint256, bytes32, bytes32, bytes32);\\n}\\n\",\"keccak256\":\"0x7ad931dd67d911bad70d61299f5c4208ca68cadcbe1d06a14dcf9fb812074e8b\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523480156200001157600080fd5b5060405162001e8538038062001e858339810160408190526200003491620001d0565b84848484846200004433620000a2565b6001600160a01b03851660805260016200005f8382620002fe565b5060026200006e8282620002fe565b5050600380546001600160a01b0319166001600160a01b03949094169390931790925560045550620003ca95505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200010857600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200013357600080fd5b81516001600160401b03808211156200015057620001506200010b565b604051601f8301601f19908116603f011681019082821181831017156200017b576200017b6200010b565b816040528381526020925086838588010111156200019857600080fd5b600091505b83821015620001bc57858201830151818301840152908201906200019d565b600093810190920192909252949350505050565b600080600080600060a08688031215620001e957600080fd5b8551620001f681620000f2565b60208701519095506200020981620000f2565b6040870151606088015191955093506001600160401b03808211156200022e57600080fd5b6200023c89838a0162000121565b935060808801519150808211156200025357600080fd5b50620002628882890162000121565b9150509295509295909350565b600181811c908216806200028457607f821691505b602082108103620002a557634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002f957600081815260208120601f850160051c81016020861015620002d45750805b601f850160051c820191505b81811015620002f557828155600101620002e0565b5050505b505050565b81516001600160401b038111156200031a576200031a6200010b565b62000332816200032b84546200026f565b84620002ab565b602080601f8311600181146200036a5760008415620003515750858301515b600019600386901b1c1916600185901b178555620002f5565b600085815260208120601f198616915b828110156200039b578886015182559484019460019091019084016200037a565b5085821015620003ba5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051611a99620003ec6000396000818160b301526102b50152611a996000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063b870676c11610071578063b870676c14610135578063dbac582114610148578063f20333c11461015f578063f2fde38b1461019a578063f437bc59146101ad578063faec91e0146101b557600080fd5b806315d276e1146100ae5780635e280f11146100f2578063715018a6146101075780638da5cb5b14610111578063b2a3fda414610122575b600080fd5b6100d57f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100fa6101f5565b6040516100e99190611364565b61010f610283565b005b6000546001600160a01b03166100d5565b61010f610130366004611377565b610297565b6003546100d5906001600160a01b031681565b61015160045481565b6040519081526020016100e9565b61017261016d3660046113ac565b6102a4565b604080519586526020860194909452928401919091526060830152608082015260a0016100e9565b61010f6101a83660046113ff565b6107fa565b6100fa610873565b6101516040517413d55511d3d25391d7d410565351539517d4d15395605a1b60208201526035016040516020818303038152906040528051906020012081565b600180546102029061141a565b80601f016020809104026020016040519081016040528092919081815260200182805461022e9061141a565b801561027b5780601f106102505761010080835404028352916020019161027b565b820191906000526020600020905b81548152906001019060200180831161025e57829003601f168201915b505050505081565b61028b610880565b61029560006108da565b565b61029f610880565b600455565b600080808080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103275760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792052616d702063616e2063616c6c20746869732066756e6374696f6e60448201526064015b60405180910390fd5b610385866103358980611454565b61033e90611542565b61034b60208b018b6116c3565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061092a92505050565b6040805180820190915260018152601560f91b60208201526104db9061048d906103af8a80611454565b6103bd9060608101906116c3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060018054909250610400915061141a565b80601f016020809104026020016040519081016040528092919081815260200182805461042c9061141a565b80156104795780601f1061044e57610100808354040283529160200191610479565b820191906000526020600020905b81548152906001019060200180831161045c57829003601f168201915b50505050506109869092919063ffffffff16565b6104978980611454565b6104a190806116c3565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610a0b92505050565b6105bf600280546104eb9061141a565b80601f01602080910402602001604051908101604052809291908181526020018280546105179061141a565b80156105645780601f1061053957610100808354040283529160200191610564565b820191906000526020600020905b81548152906001019060200180831161054757829003601f168201915b5061057793508c92508291506114549050565b6105859060208101906116c3565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610aaa92505050565b6040517413d55511d3d25391d7d410565351539517d4d15395605a1b602082015260350160408051601f1981840301815291905280516020909101206106058880611454565b6106139060e08101906116c3565b60405160200161062492919061170a565b60405160208183030381529060405280519060200120146106935760405162461bcd60e51b8152602060048201526024808201527f5061796d656e7420737461747573206e6f7420636f6e6669726d6564206173206044820152631cd95b9d60e21b606482015260840161031e565b6106da6106a08880611454565b6106ae9060408101906116c3565b6040516020016106bf92919061171a565b60405160208183030381529060405280519060200120610b45565b61073460066106e98980611454565b6106f79060a08101906116c3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293925050610c609050565b6004549095506103e861075b600061074c8b80611454565b6106f7906101008101906116c3565b6107659190611750565b61076f9190611772565b935061078e60006107808980611454565b6106f79060808101906116c3565b92506107ad600061079f8980611454565b6106f79060608101906116c3565b91506107b98780611454565b6107c79060c08101906116c3565b6040516020016107d892919061170a565b6040516020818303038152906040528051906020012090509295509295909350565b610802610880565b6001600160a01b0381166108675760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161031e565b610870816108da565b50565b600280546102029061141a565b6000546001600160a01b031633146102955760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161031e565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610935838383610c7a565b6109815760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e61747572652066726f6d20766572696669657200604482015260640161031e565b505050565b6060838360006109968383610cef565b905060001981036109ac57869350505050610a04565b60006109ba88600084610dce565b905060006109d6898551856109cf9190611772565b8751610dce565b90508187826040516020016109ed93929190611785565b604051602081830303815290604052955050505050505b9392505050565b80604051602001610a1c9190611364565b6040516020818303038152906040528051906020012082604051602001610a439190611364565b6040516020818303038152906040528051906020012014610aa65760405162461bcd60e51b815260206004820181905260248201527f456e64706f696e7420646f6573206e6f74206d61746368206578706563746564604482015260640161031e565b5050565b80604051602001610abb9190611364565b6040516020818303038152906040528051906020012082604051602001610ae29190611364565b6040516020818303038152906040528051906020012014610aa65760405162461bcd60e51b815260206004820152601c60248201527f486f737420646f6573206e6f74206d6174636820657870656374656400000000604482015260640161031e565b60035460405163169394bb60e01b8152600481018390526001600160a01b039091169063169394bb90602401602060405180830381865afa158015610b8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb291906117c8565b15610bff5760405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e207573656400604482015260640161031e565b600354604051632dea6f9960e11b8152600481018390526001600160a01b0390911690635bd4df3290602401600060405180830381600087803b158015610c4557600080fd5b505af1158015610c59573d6000803e3d6000fd5b5050505050565b6000610c7183601760f91b84610e9b565b90505b92915050565b600080836000015184602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001518c6101200151604051602001610cca9a999897969594939291906117ea565b6040516020818303038152906040529050610ce6818487611078565b95945050505050565b80518251600091849184911115610d0c5760001992505050610c74565b60005b81518351610d1d91906118b8565b8111610dc157600160005b8351811015610d9c57838181518110610d4357610d436118cb565b01602001516001600160f81b03191685610d5d8386611772565b81518110610d6d57610d6d6118cb565b01602001516001600160f81b03191614610d8a5760009150610d9c565b80610d94816118e1565b915050610d28565b508015610dae57509250610c74915050565b5080610db9816118e1565b915050610d0f565b5060001995945050505050565b6060836000610ddd85856118b8565b67ffffffffffffffff811115610df557610df5611475565b6040519080825280601f01601f191660200182016040528015610e1f576020820181803683370190505b509050845b84811015610e9157828181518110610e3e57610e3e6118cb565b01602001516001600160f81b03191682610e5888846118b8565b81518110610e6857610e686118cb565b60200101906001600160f81b031916908160001a90535080610e89816118e1565b915050610e24565b5095945050505050565b600083818080805b8451811015610ff157603060f81b858281518110610ec357610ec36118cb565b01602001516001600160f81b03191610801590610f045750603960f81b858281518110610ef257610ef26118cb565b01602001516001600160f81b03191611155b15610f47576030858281518110610f1d57610f1d6118cb565b0160200151610f2f919060f81c6118b8565b610f3a85600a6118fa565b610f449190611772565b93505b8115610f5b5782610f57816118e1565b9350505b876001600160f81b031916858281518110610f7857610f786118cb565b01602001516001600160f81b03191603610fdf578115610fda5760405162461bcd60e51b815260206004820152601c60248201527f537472696e6720686173206d756c7469706c6520646563696d616c7300000000604482015260640161031e565b600191505b80610fe9816118e1565b915050610ea3565b508582111561104d5760405162461bcd60e51b815260206004820152602260248201527f537472696e672068617320746f6f206d616e7920646563696d616c20706c6163604482015261657360f01b606482015260840161031e565b61105782876118b8565b61106290600a6119f5565b61106c90846118fa565b98975050505050505050565b825160208401207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c8120610ce66001600160a01b038416828660008060006110cd858561111f565b909250905060008160048111156110e6576110e6611a01565b1480156111045750856001600160a01b0316826001600160a01b0316145b806111155750611115868686611164565b9695505050505050565b60008082516041036111555760208301516040840151606085015160001a61114987828585611250565b9450945050505061115d565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b868660405160240161118e929190611a17565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516111cc9190611a38565b600060405180830381855afa9150503d8060008114611207576040519150601f19603f3d011682016040523d82523d6000602084013e61120c565b606091505b509150915081801561122057506020815110155b801561111557508051630b135d3f60e11b906112459083016020908101908401611a4a565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611287575060009050600361130b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156112db573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166113045760006001925092505061130b565b9150600090505b94509492505050565b60005b8381101561132f578181015183820152602001611317565b50506000910152565b60008151808452611350816020860160208601611314565b601f01601f19169290920160200192915050565b602081526000610c716020830184611338565b60006020828403121561138957600080fd5b5035919050565b80356001600160a01b03811681146113a757600080fd5b919050565b600080604083850312156113bf57600080fd5b823567ffffffffffffffff8111156113d657600080fd5b8301604081860312156113e857600080fd5b91506113f660208401611390565b90509250929050565b60006020828403121561141157600080fd5b610c7182611390565b600181811c9082168061142e57607f821691505b60208210810361144e57634e487b7160e01b600052602260045260246000fd5b50919050565b6000823561013e1983360301811261146b57600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156114af576114af611475565b60405290565b600082601f8301126114c657600080fd5b813567ffffffffffffffff808211156114e1576114e1611475565b604051601f8301601f19908116603f0116810190828211818310171561150957611509611475565b8160405283815286602085880101111561152257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610140823603121561155557600080fd5b61155d61148b565b823567ffffffffffffffff8082111561157557600080fd5b611581368387016114b5565b8352602085013591508082111561159757600080fd5b6115a3368387016114b5565b602084015260408501359150808211156115bc57600080fd5b6115c8368387016114b5565b604084015260608501359150808211156115e157600080fd5b6115ed368387016114b5565b6060840152608085013591508082111561160657600080fd5b611612368387016114b5565b608084015260a085013591508082111561162b57600080fd5b611637368387016114b5565b60a084015260c085013591508082111561165057600080fd5b61165c368387016114b5565b60c084015260e085013591508082111561167557600080fd5b611681368387016114b5565b60e08401526101009150818501358181111561169c57600080fd5b6116a8368288016114b5565b92840192909252505061012092830135928101929092525090565b6000808335601e198436030181126116da57600080fd5b83018035915067ffffffffffffffff8211156116f557600080fd5b60200191503681900382131561115d57600080fd5b8183823760009101908152919050565b635769736560e01b81528183600483013760009101600401908152919050565b634e487b7160e01b600052601160045260246000fd5b60008261176d57634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610c7457610c7461173a565b60008451611797818460208901611314565b8451908301906117ab818360208901611314565b84519101906117be818360208801611314565b0195945050505050565b6000602082840312156117da57600080fd5b81518015158114610a0457600080fd5b60006101408083526117fe8184018e611338565b90508281036020840152611812818d611338565b90508281036040840152611826818c611338565b9050828103606084015261183a818b611338565b9050828103608084015261184e818a611338565b905082810360a08401526118628189611338565b905082810360c08401526118768188611338565b905082810360e084015261188a8187611338565b905082810361010084015261189f8186611338565b915050826101208301529b9a5050505050505050505050565b81810381811115610c7457610c7461173a565b634e487b7160e01b600052603260045260246000fd5b6000600182016118f3576118f361173a565b5060010190565b8082028115828204841417610c7457610c7461173a565b600181815b8085111561194c5781600019048211156119325761193261173a565b8085161561193f57918102915b93841c9390800290611916565b509250929050565b60008261196357506001610c74565b8161197057506000610c74565b81600181146119865760028114611990576119ac565b6001915050610c74565b60ff8411156119a1576119a161173a565b50506001821b610c74565b5060208310610133831016604e8410600b84101617156119cf575081810a610c74565b6119d98383611911565b80600019048211156119ed576119ed61173a565b029392505050565b6000610c718383611954565b634e487b7160e01b600052602160045260246000fd5b828152604060208201526000611a306040830184611338565b949350505050565b6000825161146b818460208701611314565b600060208284031215611a5c57600080fd5b505191905056fea26469706673582212203b28ab247969e751fa64a5efd1e80a7ebf11f0ffdf516cdfae7150a276220f9b64736f6c63430008120033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a95760003560e01c8063b870676c11610071578063b870676c14610135578063dbac582114610148578063f20333c11461015f578063f2fde38b1461019a578063f437bc59146101ad578063faec91e0146101b557600080fd5b806315d276e1146100ae5780635e280f11146100f2578063715018a6146101075780638da5cb5b14610111578063b2a3fda414610122575b600080fd5b6100d57f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100fa6101f5565b6040516100e99190611364565b61010f610283565b005b6000546001600160a01b03166100d5565b61010f610130366004611377565b610297565b6003546100d5906001600160a01b031681565b61015160045481565b6040519081526020016100e9565b61017261016d3660046113ac565b6102a4565b604080519586526020860194909452928401919091526060830152608082015260a0016100e9565b61010f6101a83660046113ff565b6107fa565b6100fa610873565b6101516040517413d55511d3d25391d7d410565351539517d4d15395605a1b60208201526035016040516020818303038152906040528051906020012081565b600180546102029061141a565b80601f016020809104026020016040519081016040528092919081815260200182805461022e9061141a565b801561027b5780601f106102505761010080835404028352916020019161027b565b820191906000526020600020905b81548152906001019060200180831161025e57829003601f168201915b505050505081565b61028b610880565b61029560006108da565b565b61029f610880565b600455565b600080808080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103275760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792052616d702063616e2063616c6c20746869732066756e6374696f6e60448201526064015b60405180910390fd5b610385866103358980611454565b61033e90611542565b61034b60208b018b6116c3565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061092a92505050565b6040805180820190915260018152601560f91b60208201526104db9061048d906103af8a80611454565b6103bd9060608101906116c3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060018054909250610400915061141a565b80601f016020809104026020016040519081016040528092919081815260200182805461042c9061141a565b80156104795780601f1061044e57610100808354040283529160200191610479565b820191906000526020600020905b81548152906001019060200180831161045c57829003601f168201915b50505050506109869092919063ffffffff16565b6104978980611454565b6104a190806116c3565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610a0b92505050565b6105bf600280546104eb9061141a565b80601f01602080910402602001604051908101604052809291908181526020018280546105179061141a565b80156105645780601f1061053957610100808354040283529160200191610564565b820191906000526020600020905b81548152906001019060200180831161054757829003601f168201915b5061057793508c92508291506114549050565b6105859060208101906116c3565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610aaa92505050565b6040517413d55511d3d25391d7d410565351539517d4d15395605a1b602082015260350160408051601f1981840301815291905280516020909101206106058880611454565b6106139060e08101906116c3565b60405160200161062492919061170a565b60405160208183030381529060405280519060200120146106935760405162461bcd60e51b8152602060048201526024808201527f5061796d656e7420737461747573206e6f7420636f6e6669726d6564206173206044820152631cd95b9d60e21b606482015260840161031e565b6106da6106a08880611454565b6106ae9060408101906116c3565b6040516020016106bf92919061171a565b60405160208183030381529060405280519060200120610b45565b61073460066106e98980611454565b6106f79060a08101906116c3565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293925050610c609050565b6004549095506103e861075b600061074c8b80611454565b6106f7906101008101906116c3565b6107659190611750565b61076f9190611772565b935061078e60006107808980611454565b6106f79060808101906116c3565b92506107ad600061079f8980611454565b6106f79060608101906116c3565b91506107b98780611454565b6107c79060c08101906116c3565b6040516020016107d892919061170a565b6040516020818303038152906040528051906020012090509295509295909350565b610802610880565b6001600160a01b0381166108675760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161031e565b610870816108da565b50565b600280546102029061141a565b6000546001600160a01b031633146102955760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161031e565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610935838383610c7a565b6109815760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e61747572652066726f6d20766572696669657200604482015260640161031e565b505050565b6060838360006109968383610cef565b905060001981036109ac57869350505050610a04565b60006109ba88600084610dce565b905060006109d6898551856109cf9190611772565b8751610dce565b90508187826040516020016109ed93929190611785565b604051602081830303815290604052955050505050505b9392505050565b80604051602001610a1c9190611364565b6040516020818303038152906040528051906020012082604051602001610a439190611364565b6040516020818303038152906040528051906020012014610aa65760405162461bcd60e51b815260206004820181905260248201527f456e64706f696e7420646f6573206e6f74206d61746368206578706563746564604482015260640161031e565b5050565b80604051602001610abb9190611364565b6040516020818303038152906040528051906020012082604051602001610ae29190611364565b6040516020818303038152906040528051906020012014610aa65760405162461bcd60e51b815260206004820152601c60248201527f486f737420646f6573206e6f74206d6174636820657870656374656400000000604482015260640161031e565b60035460405163169394bb60e01b8152600481018390526001600160a01b039091169063169394bb90602401602060405180830381865afa158015610b8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb291906117c8565b15610bff5760405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e207573656400604482015260640161031e565b600354604051632dea6f9960e11b8152600481018390526001600160a01b0390911690635bd4df3290602401600060405180830381600087803b158015610c4557600080fd5b505af1158015610c59573d6000803e3d6000fd5b5050505050565b6000610c7183601760f91b84610e9b565b90505b92915050565b600080836000015184602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001518c6101200151604051602001610cca9a999897969594939291906117ea565b6040516020818303038152906040529050610ce6818487611078565b95945050505050565b80518251600091849184911115610d0c5760001992505050610c74565b60005b81518351610d1d91906118b8565b8111610dc157600160005b8351811015610d9c57838181518110610d4357610d436118cb565b01602001516001600160f81b03191685610d5d8386611772565b81518110610d6d57610d6d6118cb565b01602001516001600160f81b03191614610d8a5760009150610d9c565b80610d94816118e1565b915050610d28565b508015610dae57509250610c74915050565b5080610db9816118e1565b915050610d0f565b5060001995945050505050565b6060836000610ddd85856118b8565b67ffffffffffffffff811115610df557610df5611475565b6040519080825280601f01601f191660200182016040528015610e1f576020820181803683370190505b509050845b84811015610e9157828181518110610e3e57610e3e6118cb565b01602001516001600160f81b03191682610e5888846118b8565b81518110610e6857610e686118cb565b60200101906001600160f81b031916908160001a90535080610e89816118e1565b915050610e24565b5095945050505050565b600083818080805b8451811015610ff157603060f81b858281518110610ec357610ec36118cb565b01602001516001600160f81b03191610801590610f045750603960f81b858281518110610ef257610ef26118cb565b01602001516001600160f81b03191611155b15610f47576030858281518110610f1d57610f1d6118cb565b0160200151610f2f919060f81c6118b8565b610f3a85600a6118fa565b610f449190611772565b93505b8115610f5b5782610f57816118e1565b9350505b876001600160f81b031916858281518110610f7857610f786118cb565b01602001516001600160f81b03191603610fdf578115610fda5760405162461bcd60e51b815260206004820152601c60248201527f537472696e6720686173206d756c7469706c6520646563696d616c7300000000604482015260640161031e565b600191505b80610fe9816118e1565b915050610ea3565b508582111561104d5760405162461bcd60e51b815260206004820152602260248201527f537472696e672068617320746f6f206d616e7920646563696d616c20706c6163604482015261657360f01b606482015260840161031e565b61105782876118b8565b61106290600a6119f5565b61106c90846118fa565b98975050505050505050565b825160208401207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c8120610ce66001600160a01b038416828660008060006110cd858561111f565b909250905060008160048111156110e6576110e6611a01565b1480156111045750856001600160a01b0316826001600160a01b0316145b806111155750611115868686611164565b9695505050505050565b60008082516041036111555760208301516040840151606085015160001a61114987828585611250565b9450945050505061115d565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b868660405160240161118e929190611a17565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516111cc9190611a38565b600060405180830381855afa9150503d8060008114611207576040519150601f19603f3d011682016040523d82523d6000602084013e61120c565b606091505b509150915081801561122057506020815110155b801561111557508051630b135d3f60e11b906112459083016020908101908401611a4a565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611287575060009050600361130b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156112db573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166113045760006001925092505061130b565b9150600090505b94509492505050565b60005b8381101561132f578181015183820152602001611317565b50506000910152565b60008151808452611350816020860160208601611314565b601f01601f19169290920160200192915050565b602081526000610c716020830184611338565b60006020828403121561138957600080fd5b5035919050565b80356001600160a01b03811681146113a757600080fd5b919050565b600080604083850312156113bf57600080fd5b823567ffffffffffffffff8111156113d657600080fd5b8301604081860312156113e857600080fd5b91506113f660208401611390565b90509250929050565b60006020828403121561141157600080fd5b610c7182611390565b600181811c9082168061142e57607f821691505b60208210810361144e57634e487b7160e01b600052602260045260246000fd5b50919050565b6000823561013e1983360301811261146b57600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156114af576114af611475565b60405290565b600082601f8301126114c657600080fd5b813567ffffffffffffffff808211156114e1576114e1611475565b604051601f8301601f19908116603f0116810190828211818310171561150957611509611475565b8160405283815286602085880101111561152257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610140823603121561155557600080fd5b61155d61148b565b823567ffffffffffffffff8082111561157557600080fd5b611581368387016114b5565b8352602085013591508082111561159757600080fd5b6115a3368387016114b5565b602084015260408501359150808211156115bc57600080fd5b6115c8368387016114b5565b604084015260608501359150808211156115e157600080fd5b6115ed368387016114b5565b6060840152608085013591508082111561160657600080fd5b611612368387016114b5565b608084015260a085013591508082111561162b57600080fd5b611637368387016114b5565b60a084015260c085013591508082111561165057600080fd5b61165c368387016114b5565b60c084015260e085013591508082111561167557600080fd5b611681368387016114b5565b60e08401526101009150818501358181111561169c57600080fd5b6116a8368288016114b5565b92840192909252505061012092830135928101929092525090565b6000808335601e198436030181126116da57600080fd5b83018035915067ffffffffffffffff8211156116f557600080fd5b60200191503681900382131561115d57600080fd5b8183823760009101908152919050565b635769736560e01b81528183600483013760009101600401908152919050565b634e487b7160e01b600052601160045260246000fd5b60008261176d57634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610c7457610c7461173a565b60008451611797818460208901611314565b8451908301906117ab818360208901611314565b84519101906117be818360208801611314565b0195945050505050565b6000602082840312156117da57600080fd5b81518015158114610a0457600080fd5b60006101408083526117fe8184018e611338565b90508281036020840152611812818d611338565b90508281036040840152611826818c611338565b9050828103606084015261183a818b611338565b9050828103608084015261184e818a611338565b905082810360a08401526118628189611338565b905082810360c08401526118768188611338565b905082810360e084015261188a8187611338565b905082810361010084015261189f8186611338565b915050826101208301529b9a5050505050505050505050565b81810381811115610c7457610c7461173a565b634e487b7160e01b600052603260045260246000fd5b6000600182016118f3576118f361173a565b5060010190565b8082028115828204841417610c7457610c7461173a565b600181815b8085111561194c5781600019048211156119325761193261173a565b8085161561193f57918102915b93841c9390800290611916565b509250929050565b60008261196357506001610c74565b8161197057506000610c74565b81600181146119865760028114611990576119ac565b6001915050610c74565b60ff8411156119a1576119a161173a565b50506001821b610c74565b5060208310610133831016604e8410600b84101617156119cf575081810a610c74565b6119d98383611911565b80600019048211156119ed576119ed61173a565b029392505050565b6000610c718383611954565b634e487b7160e01b600052602160045260246000fd5b828152604060208201526000611a306040830184611338565b949350505050565b6000825161146b818460208701611314565b600060208284031215611a5c57600080fd5b505191905056fea26469706673582212203b28ab247969e751fa64a5efd1e80a7ebf11f0ffdf516cdfae7150a276220f9b64736f6c63430008120033", + "solcInputHash": "0de631e329f560f49e3d6a21d19a30cc", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_ramp\",\"type\":\"address\"},{\"internalType\":\"contract INullifierRegistry\",\"name\":\"_nullifierRegistry\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_host\",\"type\":\"string\"}],\"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\"},{\"inputs\":[],\"name\":\"PAYMENT_STATUS\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"endpoint\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"host\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nullifierRegistry\",\"outputs\":[{\"internalType\":\"contract INullifierRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"endpoint\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"host\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"transferId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"senderId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"recipientId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"amount\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"currencyId\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"status\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"timestamp\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"intentHash\",\"type\":\"uint256\"}],\"internalType\":\"struct IWiseSendProcessor.SendData\",\"name\":\"public_values\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"internalType\":\"struct IWiseSendProcessor.SendProof\",\"name\":\"_proof\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"_verifierSigningKey\",\"type\":\"address\"}],\"name\":\"processProof\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"offRamperId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"currencyId\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ramp\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"}],\"name\":\"setTimestampBuffer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timestampBuffer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setTimestampBuffer(uint256)\":{\"params\":{\"_timestampBuffer\":\"The timestamp buffer for validated TLS calls\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"setTimestampBuffer(uint256)\":{\"notice\":\"ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2 timestamps.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ramps/wise/WiseSendProcessor.sol\":\"WiseSendProcessor\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"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/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/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"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\"},\"contracts/lib/StringConversionUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\n// Building on zk-email's StringUtils library we add the ability to handle decimals when\\n// converting from string to Uint\\nlibrary StringConversionUtils {\\n \\n /**\\n * @notice Function that parses numbers returned as strings including floating point numbers. Returned floating point\\n * numbers are to have the desired amount of decimal specified. If the stringified version of the floating point\\n * number has more decimal places than desired then the function will revert in order to be maximally safe. If\\n * the returned number has multiple floating points then the function will revert.\\n *\\n * Examples: _s = \\\"12.34\\\", _expectedDecimals = 6 => 12340000\\n * _s = \\\"12.34\\\", _expectedDecimals = 2 => 1234\\n * _s = \\\"12.34\\\", _expectedDecimals = 1 => REVERT (we never want loss of precision only addition)\\n * _s = \\\"12.34.56\\\", _expectedDecimals = 6 => REVERT (Invalid number)\\n *\\n * @param _s String being processed\\n * @param _desiredDecimals Desired amount of decimal places\\n */\\n function stringToUint(string memory _s, uint256 _desiredDecimals) internal pure returns (uint256) {\\n return stringToUint(_s, 0x2E, _desiredDecimals);\\n }\\n\\n function stringToUint(\\n string memory _s,\\n bytes1 _decimalCharacter,\\n uint256 _desiredDecimals\\n )\\n internal\\n pure\\n returns (uint256)\\n {\\n bytes memory b = bytes(_s);\\n\\n uint256 result = 0;\\n uint256 decimalPlaces = 0;\\n\\n bool decimals = false;\\n for (uint256 i = 0; i < b.length; i++) {\\n if (b[i] >= 0x30 && b[i] <= 0x39) {\\n result = result * 10 + (uint256(uint8(b[i])) - 48);\\n }\\n\\n if (decimals) {\\n decimalPlaces++;\\n }\\n\\n if (b[i] == _decimalCharacter) {\\n require(decimals == false, \\\"String has multiple decimals\\\");\\n decimals = true;\\n }\\n }\\n\\n require(decimalPlaces <= _desiredDecimals, \\\"String has too many decimal places\\\");\\n return result * (10 ** (_desiredDecimals - decimalPlaces));\\n }\\n\\n /**\\n * @notice Function that returns a substring from _startIndex to _endIndex (non-inclusive).\\n *\\n * @param _str String being processed\\n * @param _startIndex Index to start parsing from\\n * @param _endIndex Index to stop parsing at (index not included in result)\\n */\\n function substring(string memory _str, uint _startIndex, uint _endIndex) internal pure returns (string memory ) {\\n bytes memory strBytes = bytes(_str);\\n bytes memory result = new bytes(_endIndex-_startIndex);\\n for(uint i = _startIndex; i < _endIndex; i++) {\\n result[i-_startIndex] = strBytes[i];\\n }\\n return string(result);\\n }\\n\\n function replaceString(\\n string memory _str,\\n string memory _lookupValue,\\n string memory _replaceValue\\n )\\n internal\\n pure\\n returns (string memory)\\n {\\n bytes memory strBytes = bytes(_str);\\n bytes memory lookupBytes = bytes(_lookupValue);\\n\\n uint256 lookupIndex = indexOf(_str, _lookupValue);\\n if (lookupIndex == type(uint256).max) {\\n return _str;\\n }\\n\\n // Split the original string into two parts: before and after the keyword\\n string memory beforeKeyword = substring(_str, 0, lookupIndex);\\n string memory afterKeyword = substring(_str, lookupIndex + lookupBytes.length, strBytes.length);\\n \\n return string.concat(beforeKeyword, _replaceValue, afterKeyword);\\n }\\n\\n function indexOf(string memory str, string memory substr) internal pure returns (uint) {\\n bytes memory strBytes = bytes(str);\\n bytes memory substrBytes = bytes(substr);\\n \\n if (strBytes.length < substrBytes.length) return type(uint256).max;\\n \\n for (uint i = 0; i <= strBytes.length - substrBytes.length; i++) {\\n bool found = true;\\n for (uint j = 0; j < substrBytes.length; j++) {\\n if (strBytes[i + j] != substrBytes[j]) {\\n found = false;\\n break;\\n }\\n }\\n if (found) return i;\\n }\\n \\n return type(uint256).max;\\n }\\n\\n function stringComparison(string memory _a, string memory _b) internal pure returns (bool) {\\n return (keccak256(abi.encodePacked(_a)) == keccak256(abi.encodePacked(_b)));\\n }\\n}\\n\",\"keccak256\":\"0xfcdfb3c2c8d5a6b7f480f827049782a70fb98f8b3838dcad0e0bb95237b94a0c\",\"license\":\"MIT\"},\"contracts/processors/TLSBaseProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { ECDSA } from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { SignatureChecker } from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\n\\nimport { INullifierRegistry } from \\\"./nullifierRegistries/INullifierRegistry.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract TLSBaseProcessor is Ownable {\\n\\n using SignatureChecker for address;\\n using ECDSA for bytes32;\\n\\n /* ============ Modifiers ============ */\\n modifier onlyRamp() {\\n require(msg.sender == ramp, \\\"Only Ramp can call this function\\\");\\n _;\\n }\\n\\n /* ============ State Variables ============ */\\n address public immutable ramp;\\n string public endpoint;\\n string public host;\\n\\n INullifierRegistry public nullifierRegistry;\\n uint256 public timestampBuffer;\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _ramp,\\n INullifierRegistry _nullifierRegistry,\\n uint256 _timestampBuffer,\\n string memory _endpoint,\\n string memory _host\\n )\\n Ownable()\\n {\\n ramp = _ramp;\\n endpoint = _endpoint;\\n host = _host;\\n\\n nullifierRegistry = _nullifierRegistry;\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ External Functions ============ */\\n\\n /**\\n * @notice ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds\\n * that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2\\n * timestamps.\\n *\\n * @param _timestampBuffer The timestamp buffer for validated TLS calls\\n */\\n function setTimestampBuffer(uint256 _timestampBuffer) external onlyOwner {\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ Internal Functions ============ */\\n\\n function _validateTLSEndpoint(\\n string memory _expectedEndpoint,\\n string memory _passedEndpoint\\n )\\n internal\\n pure\\n {\\n require(\\n keccak256(abi.encode(_expectedEndpoint)) == keccak256(abi.encode(_passedEndpoint)),\\n \\\"Endpoint does not match expected\\\"\\n );\\n }\\n\\n function _validateTLSHost(\\n string memory _expectedHost,\\n string memory _passedHost\\n )\\n internal\\n pure\\n {\\n require(\\n keccak256(abi.encode(_expectedHost)) == keccak256(abi.encode(_passedHost)),\\n \\\"Host does not match expected\\\"\\n );\\n }\\n\\n function _validateAndAddNullifier(bytes32 _nullifier) internal {\\n require(!nullifierRegistry.isNullified(_nullifier), \\\"Nullifier has already been used\\\");\\n nullifierRegistry.addNullifier(_nullifier);\\n }\\n\\n function _isValidVerifierSignature(\\n bytes memory _message,\\n bytes memory _signature,\\n address _verifier\\n )\\n internal\\n view\\n returns(bool)\\n {\\n bytes32 verifierPayload = keccak256(_message).toEthSignedMessageHash();\\n\\n return _verifier.isValidSignatureNow(verifierPayload, _signature);\\n }\\n}\\n\",\"keccak256\":\"0xbbdb8f203288645916ad04ee65625fae570ed091fbf243a706df7991b29ffe61\",\"license\":\"MIT\"},\"contracts/processors/keyHashAdapters/IKeyHashAdapterV2.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IKeyHashAdapterV2 {\\n function addMailServerKeyHash(bytes32 _mailserverKeyHash) external;\\n function removeMailServerKeyHash(bytes32 _mailserverKeyHash) external;\\n function getMailServerKeyHashes() external view returns (bytes32[] memory);\\n function isMailServerKeyHash(bytes32 _mailserverKeyHash) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xc849f2dc34e4463550b8e0a16541bde429cb1adf43776b2c4179e9d4e4e656a2\",\"license\":\"MIT\"},\"contracts/processors/nullifierRegistries/INullifierRegistry.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface INullifierRegistry {\\n function addNullifier(bytes32 _nullifier) external;\\n function isNullified(bytes32 _nullifier) external view returns(bool);\\n}\\n\",\"keccak256\":\"0x107164bc9a320938b513305878163b7fa884da4cdae58d0c8e81bfbb00c97c5e\",\"license\":\"MIT\"},\"contracts/ramps/wise/WiseSendProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { ECDSA } from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport { SignatureChecker } from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\n\\nimport { IKeyHashAdapterV2 } from \\\"../../processors/keyHashAdapters/IKeyHashAdapterV2.sol\\\";\\nimport { INullifierRegistry } from \\\"../../processors/nullifierRegistries/INullifierRegistry.sol\\\";\\nimport { IWiseSendProcessor } from \\\"./interfaces/IWiseSendProcessor.sol\\\";\\nimport { StringConversionUtils } from \\\"../../lib/StringConversionUtils.sol\\\";\\nimport { TLSBaseProcessor } from \\\"../../processors/TLSBaseProcessor.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract WiseSendProcessor is IWiseSendProcessor, TLSBaseProcessor {\\n\\n using ECDSA for bytes32;\\n using SignatureChecker for address;\\n using StringConversionUtils for string;\\n\\n /* ============ Constants ============ */\\n bytes32 public constant PAYMENT_STATUS = keccak256(abi.encodePacked(\\\"OUTGOING_PAYMENT_SENT\\\"));\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _ramp,\\n INullifierRegistry _nullifierRegistry,\\n uint256 _timestampBuffer,\\n string memory _endpoint,\\n string memory _host\\n )\\n TLSBaseProcessor(\\n _ramp,\\n _nullifierRegistry,\\n _timestampBuffer,\\n _endpoint,\\n _host\\n )\\n {}\\n \\n /* ============ External Functions ============ */\\n function processProof(\\n IWiseSendProcessor.SendProof calldata _proof,\\n address _verifierSigningKey\\n )\\n public\\n override\\n onlyRamp\\n returns(\\n uint256 amount,\\n uint256 timestamp,\\n bytes32 offRamperId,\\n bytes32 currencyId\\n )\\n {\\n _validateProof(_verifierSigningKey, _proof.public_values, _proof.proof);\\n\\n _validateTLSEndpoint(\\n endpoint.replaceString(\\\"*\\\", _proof.public_values.senderId),\\n _proof.public_values.endpoint\\n );\\n _validateTLSHost(host, _proof.public_values.host);\\n \\n // Validate status\\n require(\\n keccak256(abi.encodePacked(_proof.public_values.status)) == PAYMENT_STATUS,\\n \\\"Payment status not confirmed as sent\\\"\\n );\\n _validateAndAddNullifier(keccak256(abi.encodePacked(\\\"Wise\\\", _proof.public_values.transferId)));\\n\\n amount = _proof.public_values.amount.stringToUint(6);\\n\\n // Add the buffer to build in flexibility with L2 timestamps\\n timestamp = _proof.public_values.timestamp.stringToUint(0) / 1000 + timestampBuffer;\\n\\n offRamperId = bytes32(_proof.public_values.recipientId.stringToUint(0));\\n currencyId = keccak256(abi.encodePacked(_proof.public_values.currencyId));\\n }\\n\\n /* ============ View Functions ============ */\\n\\n function verifyProof(\\n address _verifierSigningKey,\\n IWiseSendProcessor.SendData memory _publicValues, \\n bytes memory _proof\\n )\\n internal\\n view\\n returns(bool)\\n { \\n bytes memory encodedMessage = abi.encode(\\n _publicValues.endpoint,\\n _publicValues.host,\\n _publicValues.transferId,\\n _publicValues.senderId,\\n _publicValues.recipientId,\\n _publicValues.amount,\\n _publicValues.currencyId,\\n _publicValues.status,\\n _publicValues.timestamp,\\n _publicValues.intentHash\\n );\\n return _isValidVerifierSignature(encodedMessage, _proof, _verifierSigningKey);\\n }\\n\\n /* ============ Internal Functions ============ */\\n\\n function _validateProof(\\n address _verifierSigningKey,\\n IWiseSendProcessor.SendData memory _publicValues, \\n bytes memory _proof\\n )\\n internal\\n view\\n { \\n require(\\n verifyProof(_verifierSigningKey, _publicValues, _proof),\\n \\\"Invalid signature from verifier\\\"\\n );\\n }\\n}\\n\",\"keccak256\":\"0xe7b25a98996bf8d61ed6ad4493e796bff5deba6adec80fc99daeb30ba824a2b6\",\"license\":\"MIT\"},\"contracts/ramps/wise/interfaces/IWiseSendProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.18;\\n\\ninterface IWiseSendProcessor {\\n\\n struct SendData {\\n string endpoint;\\n string host;\\n string transferId;\\n string senderId;\\n string recipientId;\\n string amount;\\n string currencyId;\\n string status;\\n string timestamp;\\n uint256 intentHash;\\n }\\n\\n struct SendProof {\\n SendData public_values;\\n bytes proof;\\n }\\n\\n function processProof(\\n SendProof calldata _proof,\\n address _verifierSigningKey\\n )\\n external\\n returns(uint256, uint256, bytes32, bytes32);\\n}\\n\",\"keccak256\":\"0x019b7fbd91e5b77bd9d9eae23d2b6b4af1a7248dc2320114ce2528f4095bc4c8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162001e5c38038062001e5c8339810160408190526200003491620001d0565b84848484846200004433620000a2565b6001600160a01b03851660805260016200005f8382620002fe565b5060026200006e8282620002fe565b5050600380546001600160a01b0319166001600160a01b03949094169390931790925560045550620003ca95505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200010857600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200013357600080fd5b81516001600160401b03808211156200015057620001506200010b565b604051601f8301601f19908116603f011681019082821181831017156200017b576200017b6200010b565b816040528381526020925086838588010111156200019857600080fd5b600091505b83821015620001bc57858201830151818301840152908201906200019d565b600093810190920192909252949350505050565b600080600080600060a08688031215620001e957600080fd5b8551620001f681620000f2565b60208701519095506200020981620000f2565b6040870151606088015191955093506001600160401b03808211156200022e57600080fd5b6200023c89838a0162000121565b935060808801519150808211156200025357600080fd5b50620002628882890162000121565b9150509295509295909350565b600181811c908216806200028457607f821691505b602082108103620002a557634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002f957600081815260208120601f850160051c81016020861015620002d45750805b601f850160051c820191505b81811015620002f557828155600101620002e0565b5050505b505050565b81516001600160401b038111156200031a576200031a6200010b565b62000332816200032b84546200026f565b84620002ab565b602080601f8311600181146200036a5760008415620003515750858301515b600019600386901b1c1916600185901b178555620002f5565b600085815260208120601f198616915b828110156200039b578886015182559484019460019091019084016200037a565b5085821015620003ba5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051611a70620003ec6000396000818160b301526102ac0152611a706000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063b870676c11610071578063b870676c14610135578063dbac582114610148578063f20333c11461015f578063f2fde38b14610192578063f437bc59146101a5578063faec91e0146101ad57600080fd5b806315d276e1146100ae5780635e280f11146100f2578063715018a6146101075780638da5cb5b14610111578063b2a3fda414610122575b600080fd5b6100d57f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100fa6101ed565b6040516100e9919061133b565b61010f61027b565b005b6000546001600160a01b03166100d5565b61010f61013036600461134e565b61028f565b6003546100d5906001600160a01b031681565b61015160045481565b6040519081526020016100e9565b61017261016d366004611383565b61029c565b6040805194855260208501939093529183015260608201526080016100e9565b61010f6101a03660046113d6565b6107d1565b6100fa61084a565b6101516040517413d55511d3d25391d7d410565351539517d4d15395605a1b60208201526035016040516020818303038152906040528051906020012081565b600180546101fa906113f1565b80601f0160208091040260200160405190810160405280929190818152602001828054610226906113f1565b80156102735780601f1061024857610100808354040283529160200191610273565b820191906000526020600020905b81548152906001019060200180831161025657829003601f168201915b505050505081565b610283610857565b61028d60006108b1565b565b610297610857565b600455565b6000808080336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461031e5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792052616d702063616e2063616c6c20746869732066756e6374696f6e60448201526064015b60405180910390fd5b61037c8561032c888061142b565b61033590611519565b61034260208a018a61169a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061090192505050565b6040805180820190915260018152601560f91b60208201526104d290610484906103a6898061142b565b6103b490606081019061169a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050600180549092506103f791506113f1565b80601f0160208091040260200160405190810160405280929190818152602001828054610423906113f1565b80156104705780601f1061044557610100808354040283529160200191610470565b820191906000526020600020905b81548152906001019060200180831161045357829003601f168201915b505050505061095d9092919063ffffffff16565b61048e888061142b565b610498908061169a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506109e292505050565b6105b6600280546104e2906113f1565b80601f016020809104026020016040519081016040528092919081815260200182805461050e906113f1565b801561055b5780601f106105305761010080835404028352916020019161055b565b820191906000526020600020905b81548152906001019060200180831161053e57829003601f168201915b5061056e93508b925082915061142b9050565b61057c90602081019061169a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610a8192505050565b6040517413d55511d3d25391d7d410565351539517d4d15395605a1b602082015260350160408051601f1981840301815291905280516020909101206105fc878061142b565b61060a9060e081019061169a565b60405160200161061b9291906116e1565b604051602081830303815290604052805190602001201461068a5760405162461bcd60e51b8152602060048201526024808201527f5061796d656e7420737461747573206e6f7420636f6e6669726d6564206173206044820152631cd95b9d60e21b6064820152608401610315565b6106d1610697878061142b565b6106a590604081019061169a565b6040516020016106b69291906116f1565b60405160208183030381529060405280519060200120610b1c565b61072b60066106e0888061142b565b6106ee9060a081019061169a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293925050610c379050565b6004549094506103e861075260006107438a8061142b565b6106ee9061010081019061169a565b61075c9190611727565b6107669190611749565b92506107856000610777888061142b565b6106ee90608081019061169a565b9150610791868061142b565b61079f9060c081019061169a565b6040516020016107b09291906116e1565b60405160208183030381529060405280519060200120905092959194509250565b6107d9610857565b6001600160a01b03811661083e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610315565b610847816108b1565b50565b600280546101fa906113f1565b6000546001600160a01b0316331461028d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610315565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61090c838383610c51565b6109585760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e61747572652066726f6d207665726966696572006044820152606401610315565b505050565b60608383600061096d8383610cc6565b90506000198103610983578693505050506109db565b600061099188600084610da5565b905060006109ad898551856109a69190611749565b8751610da5565b90508187826040516020016109c49392919061175c565b604051602081830303815290604052955050505050505b9392505050565b806040516020016109f3919061133b565b6040516020818303038152906040528051906020012082604051602001610a1a919061133b565b6040516020818303038152906040528051906020012014610a7d5760405162461bcd60e51b815260206004820181905260248201527f456e64706f696e7420646f6573206e6f74206d617463682065787065637465646044820152606401610315565b5050565b80604051602001610a92919061133b565b6040516020818303038152906040528051906020012082604051602001610ab9919061133b565b6040516020818303038152906040528051906020012014610a7d5760405162461bcd60e51b815260206004820152601c60248201527f486f737420646f6573206e6f74206d61746368206578706563746564000000006044820152606401610315565b60035460405163169394bb60e01b8152600481018390526001600160a01b039091169063169394bb90602401602060405180830381865afa158015610b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b89919061179f565b15610bd65760405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e2075736564006044820152606401610315565b600354604051632dea6f9960e11b8152600481018390526001600160a01b0390911690635bd4df3290602401600060405180830381600087803b158015610c1c57600080fd5b505af1158015610c30573d6000803e3d6000fd5b5050505050565b6000610c4883601760f91b84610e72565b90505b92915050565b600080836000015184602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001518c6101200151604051602001610ca19a999897969594939291906117c1565b6040516020818303038152906040529050610cbd81848761104f565b95945050505050565b80518251600091849184911115610ce35760001992505050610c4b565b60005b81518351610cf4919061188f565b8111610d9857600160005b8351811015610d7357838181518110610d1a57610d1a6118a2565b01602001516001600160f81b03191685610d348386611749565b81518110610d4457610d446118a2565b01602001516001600160f81b03191614610d615760009150610d73565b80610d6b816118b8565b915050610cff565b508015610d8557509250610c4b915050565b5080610d90816118b8565b915050610ce6565b5060001995945050505050565b6060836000610db4858561188f565b67ffffffffffffffff811115610dcc57610dcc61144c565b6040519080825280601f01601f191660200182016040528015610df6576020820181803683370190505b509050845b84811015610e6857828181518110610e1557610e156118a2565b01602001516001600160f81b03191682610e2f888461188f565b81518110610e3f57610e3f6118a2565b60200101906001600160f81b031916908160001a90535080610e60816118b8565b915050610dfb565b5095945050505050565b600083818080805b8451811015610fc857603060f81b858281518110610e9a57610e9a6118a2565b01602001516001600160f81b03191610801590610edb5750603960f81b858281518110610ec957610ec96118a2565b01602001516001600160f81b03191611155b15610f1e576030858281518110610ef457610ef46118a2565b0160200151610f06919060f81c61188f565b610f1185600a6118d1565b610f1b9190611749565b93505b8115610f325782610f2e816118b8565b9350505b876001600160f81b031916858281518110610f4f57610f4f6118a2565b01602001516001600160f81b03191603610fb6578115610fb15760405162461bcd60e51b815260206004820152601c60248201527f537472696e6720686173206d756c7469706c6520646563696d616c73000000006044820152606401610315565b600191505b80610fc0816118b8565b915050610e7a565b50858211156110245760405162461bcd60e51b815260206004820152602260248201527f537472696e672068617320746f6f206d616e7920646563696d616c20706c6163604482015261657360f01b6064820152608401610315565b61102e828761188f565b61103990600a6119cc565b61104390846118d1565b98975050505050505050565b825160208401207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c8120610cbd6001600160a01b038416828660008060006110a485856110f6565b909250905060008160048111156110bd576110bd6119d8565b1480156110db5750856001600160a01b0316826001600160a01b0316145b806110ec57506110ec86868661113b565b9695505050505050565b600080825160410361112c5760208301516040840151606085015160001a61112087828585611227565b94509450505050611134565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b86866040516024016111659291906119ee565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516111a39190611a0f565b600060405180830381855afa9150503d80600081146111de576040519150601f19603f3d011682016040523d82523d6000602084013e6111e3565b606091505b50915091508180156111f757506020815110155b80156110ec57508051630b135d3f60e11b9061121c9083016020908101908401611a21565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561125e57506000905060036112e2565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156112b2573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166112db576000600192509250506112e2565b9150600090505b94509492505050565b60005b838110156113065781810151838201526020016112ee565b50506000910152565b600081518084526113278160208601602086016112eb565b601f01601f19169290920160200192915050565b602081526000610c48602083018461130f565b60006020828403121561136057600080fd5b5035919050565b80356001600160a01b038116811461137e57600080fd5b919050565b6000806040838503121561139657600080fd5b823567ffffffffffffffff8111156113ad57600080fd5b8301604081860312156113bf57600080fd5b91506113cd60208401611367565b90509250929050565b6000602082840312156113e857600080fd5b610c4882611367565b600181811c9082168061140557607f821691505b60208210810361142557634e487b7160e01b600052602260045260246000fd5b50919050565b6000823561013e1983360301811261144257600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156114865761148661144c565b60405290565b600082601f83011261149d57600080fd5b813567ffffffffffffffff808211156114b8576114b861144c565b604051601f8301601f19908116603f011681019082821181831017156114e0576114e061144c565b816040528381528660208588010111156114f957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610140823603121561152c57600080fd5b611534611462565b823567ffffffffffffffff8082111561154c57600080fd5b6115583683870161148c565b8352602085013591508082111561156e57600080fd5b61157a3683870161148c565b6020840152604085013591508082111561159357600080fd5b61159f3683870161148c565b604084015260608501359150808211156115b857600080fd5b6115c43683870161148c565b606084015260808501359150808211156115dd57600080fd5b6115e93683870161148c565b608084015260a085013591508082111561160257600080fd5b61160e3683870161148c565b60a084015260c085013591508082111561162757600080fd5b6116333683870161148c565b60c084015260e085013591508082111561164c57600080fd5b6116583683870161148c565b60e08401526101009150818501358181111561167357600080fd5b61167f3682880161148c565b92840192909252505061012092830135928101929092525090565b6000808335601e198436030181126116b157600080fd5b83018035915067ffffffffffffffff8211156116cc57600080fd5b60200191503681900382131561113457600080fd5b8183823760009101908152919050565b635769736560e01b81528183600483013760009101600401908152919050565b634e487b7160e01b600052601160045260246000fd5b60008261174457634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610c4b57610c4b611711565b6000845161176e8184602089016112eb565b8451908301906117828183602089016112eb565b84519101906117958183602088016112eb565b0195945050505050565b6000602082840312156117b157600080fd5b815180151581146109db57600080fd5b60006101408083526117d58184018e61130f565b905082810360208401526117e9818d61130f565b905082810360408401526117fd818c61130f565b90508281036060840152611811818b61130f565b90508281036080840152611825818a61130f565b905082810360a0840152611839818961130f565b905082810360c084015261184d818861130f565b905082810360e0840152611861818761130f565b9050828103610100840152611876818661130f565b915050826101208301529b9a5050505050505050505050565b81810381811115610c4b57610c4b611711565b634e487b7160e01b600052603260045260246000fd5b6000600182016118ca576118ca611711565b5060010190565b8082028115828204841417610c4b57610c4b611711565b600181815b8085111561192357816000190482111561190957611909611711565b8085161561191657918102915b93841c93908002906118ed565b509250929050565b60008261193a57506001610c4b565b8161194757506000610c4b565b816001811461195d576002811461196757611983565b6001915050610c4b565b60ff84111561197857611978611711565b50506001821b610c4b565b5060208310610133831016604e8410600b84101617156119a6575081810a610c4b565b6119b083836118e8565b80600019048211156119c4576119c4611711565b029392505050565b6000610c48838361192b565b634e487b7160e01b600052602160045260246000fd5b828152604060208201526000611a07604083018461130f565b949350505050565b600082516114428184602087016112eb565b600060208284031215611a3357600080fd5b505191905056fea2646970667358221220086121272b6439f89ad451eeb4ff7a4b10ddb5b94bc88489745c7baa3e34cd5964736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a95760003560e01c8063b870676c11610071578063b870676c14610135578063dbac582114610148578063f20333c11461015f578063f2fde38b14610192578063f437bc59146101a5578063faec91e0146101ad57600080fd5b806315d276e1146100ae5780635e280f11146100f2578063715018a6146101075780638da5cb5b14610111578063b2a3fda414610122575b600080fd5b6100d57f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100fa6101ed565b6040516100e9919061133b565b61010f61027b565b005b6000546001600160a01b03166100d5565b61010f61013036600461134e565b61028f565b6003546100d5906001600160a01b031681565b61015160045481565b6040519081526020016100e9565b61017261016d366004611383565b61029c565b6040805194855260208501939093529183015260608201526080016100e9565b61010f6101a03660046113d6565b6107d1565b6100fa61084a565b6101516040517413d55511d3d25391d7d410565351539517d4d15395605a1b60208201526035016040516020818303038152906040528051906020012081565b600180546101fa906113f1565b80601f0160208091040260200160405190810160405280929190818152602001828054610226906113f1565b80156102735780601f1061024857610100808354040283529160200191610273565b820191906000526020600020905b81548152906001019060200180831161025657829003601f168201915b505050505081565b610283610857565b61028d60006108b1565b565b610297610857565b600455565b6000808080336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461031e5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c792052616d702063616e2063616c6c20746869732066756e6374696f6e60448201526064015b60405180910390fd5b61037c8561032c888061142b565b61033590611519565b61034260208a018a61169a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061090192505050565b6040805180820190915260018152601560f91b60208201526104d290610484906103a6898061142b565b6103b490606081019061169a565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050600180549092506103f791506113f1565b80601f0160208091040260200160405190810160405280929190818152602001828054610423906113f1565b80156104705780601f1061044557610100808354040283529160200191610470565b820191906000526020600020905b81548152906001019060200180831161045357829003601f168201915b505050505061095d9092919063ffffffff16565b61048e888061142b565b610498908061169a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506109e292505050565b6105b6600280546104e2906113f1565b80601f016020809104026020016040519081016040528092919081815260200182805461050e906113f1565b801561055b5780601f106105305761010080835404028352916020019161055b565b820191906000526020600020905b81548152906001019060200180831161053e57829003601f168201915b5061056e93508b925082915061142b9050565b61057c90602081019061169a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610a8192505050565b6040517413d55511d3d25391d7d410565351539517d4d15395605a1b602082015260350160408051601f1981840301815291905280516020909101206105fc878061142b565b61060a9060e081019061169a565b60405160200161061b9291906116e1565b604051602081830303815290604052805190602001201461068a5760405162461bcd60e51b8152602060048201526024808201527f5061796d656e7420737461747573206e6f7420636f6e6669726d6564206173206044820152631cd95b9d60e21b6064820152608401610315565b6106d1610697878061142b565b6106a590604081019061169a565b6040516020016106b69291906116f1565b60405160208183030381529060405280519060200120610b1c565b61072b60066106e0888061142b565b6106ee9060a081019061169a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293925050610c379050565b6004549094506103e861075260006107438a8061142b565b6106ee9061010081019061169a565b61075c9190611727565b6107669190611749565b92506107856000610777888061142b565b6106ee90608081019061169a565b9150610791868061142b565b61079f9060c081019061169a565b6040516020016107b09291906116e1565b60405160208183030381529060405280519060200120905092959194509250565b6107d9610857565b6001600160a01b03811661083e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610315565b610847816108b1565b50565b600280546101fa906113f1565b6000546001600160a01b0316331461028d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610315565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61090c838383610c51565b6109585760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e61747572652066726f6d207665726966696572006044820152606401610315565b505050565b60608383600061096d8383610cc6565b90506000198103610983578693505050506109db565b600061099188600084610da5565b905060006109ad898551856109a69190611749565b8751610da5565b90508187826040516020016109c49392919061175c565b604051602081830303815290604052955050505050505b9392505050565b806040516020016109f3919061133b565b6040516020818303038152906040528051906020012082604051602001610a1a919061133b565b6040516020818303038152906040528051906020012014610a7d5760405162461bcd60e51b815260206004820181905260248201527f456e64706f696e7420646f6573206e6f74206d617463682065787065637465646044820152606401610315565b5050565b80604051602001610a92919061133b565b6040516020818303038152906040528051906020012082604051602001610ab9919061133b565b6040516020818303038152906040528051906020012014610a7d5760405162461bcd60e51b815260206004820152601c60248201527f486f737420646f6573206e6f74206d61746368206578706563746564000000006044820152606401610315565b60035460405163169394bb60e01b8152600481018390526001600160a01b039091169063169394bb90602401602060405180830381865afa158015610b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b89919061179f565b15610bd65760405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e2075736564006044820152606401610315565b600354604051632dea6f9960e11b8152600481018390526001600160a01b0390911690635bd4df3290602401600060405180830381600087803b158015610c1c57600080fd5b505af1158015610c30573d6000803e3d6000fd5b5050505050565b6000610c4883601760f91b84610e72565b90505b92915050565b600080836000015184602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001518c6101200151604051602001610ca19a999897969594939291906117c1565b6040516020818303038152906040529050610cbd81848761104f565b95945050505050565b80518251600091849184911115610ce35760001992505050610c4b565b60005b81518351610cf4919061188f565b8111610d9857600160005b8351811015610d7357838181518110610d1a57610d1a6118a2565b01602001516001600160f81b03191685610d348386611749565b81518110610d4457610d446118a2565b01602001516001600160f81b03191614610d615760009150610d73565b80610d6b816118b8565b915050610cff565b508015610d8557509250610c4b915050565b5080610d90816118b8565b915050610ce6565b5060001995945050505050565b6060836000610db4858561188f565b67ffffffffffffffff811115610dcc57610dcc61144c565b6040519080825280601f01601f191660200182016040528015610df6576020820181803683370190505b509050845b84811015610e6857828181518110610e1557610e156118a2565b01602001516001600160f81b03191682610e2f888461188f565b81518110610e3f57610e3f6118a2565b60200101906001600160f81b031916908160001a90535080610e60816118b8565b915050610dfb565b5095945050505050565b600083818080805b8451811015610fc857603060f81b858281518110610e9a57610e9a6118a2565b01602001516001600160f81b03191610801590610edb5750603960f81b858281518110610ec957610ec96118a2565b01602001516001600160f81b03191611155b15610f1e576030858281518110610ef457610ef46118a2565b0160200151610f06919060f81c61188f565b610f1185600a6118d1565b610f1b9190611749565b93505b8115610f325782610f2e816118b8565b9350505b876001600160f81b031916858281518110610f4f57610f4f6118a2565b01602001516001600160f81b03191603610fb6578115610fb15760405162461bcd60e51b815260206004820152601c60248201527f537472696e6720686173206d756c7469706c6520646563696d616c73000000006044820152606401610315565b600191505b80610fc0816118b8565b915050610e7a565b50858211156110245760405162461bcd60e51b815260206004820152602260248201527f537472696e672068617320746f6f206d616e7920646563696d616c20706c6163604482015261657360f01b6064820152608401610315565b61102e828761188f565b61103990600a6119cc565b61104390846118d1565b98975050505050505050565b825160208401207f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c8120610cbd6001600160a01b038416828660008060006110a485856110f6565b909250905060008160048111156110bd576110bd6119d8565b1480156110db5750856001600160a01b0316826001600160a01b0316145b806110ec57506110ec86868661113b565b9695505050505050565b600080825160410361112c5760208301516040840151606085015160001a61112087828585611227565b94509450505050611134565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b86866040516024016111659291906119ee565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516111a39190611a0f565b600060405180830381855afa9150503d80600081146111de576040519150601f19603f3d011682016040523d82523d6000602084013e6111e3565b606091505b50915091508180156111f757506020815110155b80156110ec57508051630b135d3f60e11b9061121c9083016020908101908401611a21565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561125e57506000905060036112e2565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156112b2573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166112db576000600192509250506112e2565b9150600090505b94509492505050565b60005b838110156113065781810151838201526020016112ee565b50506000910152565b600081518084526113278160208601602086016112eb565b601f01601f19169290920160200192915050565b602081526000610c48602083018461130f565b60006020828403121561136057600080fd5b5035919050565b80356001600160a01b038116811461137e57600080fd5b919050565b6000806040838503121561139657600080fd5b823567ffffffffffffffff8111156113ad57600080fd5b8301604081860312156113bf57600080fd5b91506113cd60208401611367565b90509250929050565b6000602082840312156113e857600080fd5b610c4882611367565b600181811c9082168061140557607f821691505b60208210810361142557634e487b7160e01b600052602260045260246000fd5b50919050565b6000823561013e1983360301811261144257600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156114865761148661144c565b60405290565b600082601f83011261149d57600080fd5b813567ffffffffffffffff808211156114b8576114b861144c565b604051601f8301601f19908116603f011681019082821181831017156114e0576114e061144c565b816040528381528660208588010111156114f957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610140823603121561152c57600080fd5b611534611462565b823567ffffffffffffffff8082111561154c57600080fd5b6115583683870161148c565b8352602085013591508082111561156e57600080fd5b61157a3683870161148c565b6020840152604085013591508082111561159357600080fd5b61159f3683870161148c565b604084015260608501359150808211156115b857600080fd5b6115c43683870161148c565b606084015260808501359150808211156115dd57600080fd5b6115e93683870161148c565b608084015260a085013591508082111561160257600080fd5b61160e3683870161148c565b60a084015260c085013591508082111561162757600080fd5b6116333683870161148c565b60c084015260e085013591508082111561164c57600080fd5b6116583683870161148c565b60e08401526101009150818501358181111561167357600080fd5b61167f3682880161148c565b92840192909252505061012092830135928101929092525090565b6000808335601e198436030181126116b157600080fd5b83018035915067ffffffffffffffff8211156116cc57600080fd5b60200191503681900382131561113457600080fd5b8183823760009101908152919050565b635769736560e01b81528183600483013760009101600401908152919050565b634e487b7160e01b600052601160045260246000fd5b60008261174457634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610c4b57610c4b611711565b6000845161176e8184602089016112eb565b8451908301906117828183602089016112eb565b84519101906117958183602088016112eb565b0195945050505050565b6000602082840312156117b157600080fd5b815180151581146109db57600080fd5b60006101408083526117d58184018e61130f565b905082810360208401526117e9818d61130f565b905082810360408401526117fd818c61130f565b90508281036060840152611811818b61130f565b90508281036080840152611825818a61130f565b905082810360a0840152611839818961130f565b905082810360c084015261184d818861130f565b905082810360e0840152611861818761130f565b9050828103610100840152611876818661130f565b915050826101208301529b9a5050505050505050505050565b81810381811115610c4b57610c4b611711565b634e487b7160e01b600052603260045260246000fd5b6000600182016118ca576118ca611711565b5060010190565b8082028115828204841417610c4b57610c4b611711565b600181815b8085111561192357816000190482111561190957611909611711565b8085161561191657918102915b93841c93908002906118ed565b509250929050565b60008261193a57506001610c4b565b8161194757506000610c4b565b816001811461195d576002811461196757611983565b6001915050610c4b565b60ff84111561197857611978611711565b50506001821b610c4b565b5060208310610133831016604e8410600b84101617156119a6575081810a610c4b565b6119b083836118e8565b80600019048211156119c4576119c4611711565b029392505050565b6000610c48838361192b565b634e487b7160e01b600052602160045260246000fd5b828152604060208201526000611a07604083018461130f565b949350505050565b600082516114428184602087016112eb565b600060208284031215611a3357600080fd5b505191905056fea2646970667358221220086121272b6439f89ad451eeb4ff7a4b10ddb5b94bc88489745c7baa3e34cd5964736f6c63430008120033", "devdoc": { "kind": "dev", "methods": { @@ -367,7 +362,7 @@ "type": "t_address" }, { - "astId": 5432, + "astId": 2831, "contract": "contracts/ramps/wise/WiseSendProcessor.sol:WiseSendProcessor", "label": "endpoint", "offset": 0, @@ -375,7 +370,7 @@ "type": "t_string_storage" }, { - "astId": 5434, + "astId": 2833, "contract": "contracts/ramps/wise/WiseSendProcessor.sol:WiseSendProcessor", "label": "host", "offset": 0, @@ -383,15 +378,15 @@ "type": "t_string_storage" }, { - "astId": 5437, + "astId": 2836, "contract": "contracts/ramps/wise/WiseSendProcessor.sol:WiseSendProcessor", "label": "nullifierRegistry", "offset": 0, "slot": "3", - "type": "t_contract(INullifierRegistry)5831" + "type": "t_contract(INullifierRegistry)3027" }, { - "astId": 5439, + "astId": 2838, "contract": "contracts/ramps/wise/WiseSendProcessor.sol:WiseSendProcessor", "label": "timestampBuffer", "offset": 0, @@ -405,7 +400,7 @@ "label": "address", "numberOfBytes": "20" }, - "t_contract(INullifierRegistry)5831": { + "t_contract(INullifierRegistry)3027": { "encoding": "inplace", "label": "contract INullifierRegistry", "numberOfBytes": "20" diff --git a/contracts/deployments/sepolia/solcInputs/0de631e329f560f49e3d6a21d19a30cc.json b/contracts/deployments/sepolia/solcInputs/0de631e329f560f49e3d6a21d19a30cc.json new file mode 100644 index 000000000..213be2393 --- /dev/null +++ b/contracts/deployments/sepolia/solcInputs/0de631e329f560f49e3d6a21d19a30cc.json @@ -0,0 +1,113 @@ +{ + "language": "Solidity", + "sources": { + "@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/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@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/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/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n }\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" + }, + "contracts/external/Bytes32ArrayUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.17;\n\n/**\n * @title Bytes32ArrayUtils\n * @author ZKP2P\n *\n * Fork of Set Protocol's AddressArrayUtils library adapted for usage with bytes32 arrays.\n */\nlibrary Bytes32ArrayUtils {\n\n uint256 constant internal MAX_INT = 2**256 - 1;\n\n /**\n * Finds the index of the first occurrence of the given element.\n * @param A The input array to search\n * @param a The value to find\n * @return Returns (index and isIn) for the first occurrence starting from index 0\n */\n function indexOf(bytes32[] memory A, bytes32 a) internal pure returns (uint256, bool) {\n uint256 length = A.length;\n for (uint256 i = 0; i < length; i++) {\n if (A[i] == a) {\n return (i, true);\n }\n }\n return (MAX_INT, false);\n }\n\n /**\n * Returns true if the value is present in the list. Uses indexOf internally.\n * @param A The input array to search\n * @param a The value to find\n * @return Returns isIn for the first occurrence starting from index 0\n */\n function contains(bytes32[] memory A, bytes32 a) internal pure returns (bool) {\n (, bool isIn) = indexOf(A, a);\n return isIn;\n }\n\n /**\n * Returns true if there are 2 elements that are the same in an array\n * @param A The input array to search\n * @return Returns boolean for the first occurrence of a duplicate\n */\n function hasDuplicate(bytes32[] memory A) internal pure returns(bool) {\n require(A.length > 0, \"A is empty\");\n\n for (uint256 i = 0; i < A.length - 1; i++) {\n bytes32 current = A[i];\n for (uint256 j = i + 1; j < A.length; j++) {\n if (current == A[j]) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * @param A The input array to search\n * @param a The bytes32 to remove\n * @return Returns the array with the object removed.\n */\n function remove(bytes32[] memory A, bytes32 a)\n internal\n pure\n returns (bytes32[] memory)\n {\n (uint256 index, bool isIn) = indexOf(A, a);\n if (!isIn) {\n revert(\"bytes32 not in array.\");\n } else {\n (bytes32[] memory _A,) = pop(A, index);\n return _A;\n }\n }\n\n /**\n * @param A The input array to search\n * @param a The bytes32 to remove\n */\n function removeStorage(bytes32[] storage A, bytes32 a)\n internal\n {\n (uint256 index, bool isIn) = indexOf(A, a);\n if (!isIn) {\n revert(\"bytes32 not in array.\");\n } else {\n uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here\n if (index != lastIndex) { A[index] = A[lastIndex]; }\n A.pop();\n }\n }\n\n /**\n * Removes specified index from array\n * @param A The input array to search\n * @param index The index to remove\n * @return Returns the new array and the removed entry\n */\n function pop(bytes32[] memory A, uint256 index)\n internal\n pure\n returns (bytes32[] memory, bytes32)\n {\n uint256 length = A.length;\n require(index < A.length, \"Index must be < A length\");\n bytes32[] memory newBytes = new bytes32[](length - 1);\n for (uint256 i = 0; i < index; i++) {\n newBytes[i] = A[i];\n }\n for (uint256 j = index + 1; j < length; j++) {\n newBytes[j - 1] = A[j];\n }\n return (newBytes, A[index]);\n }\n}\n" + }, + "contracts/external/Uint256ArrayUtils.sol": { + "content": "/*\n Copyright 2020 Set Labs Inc.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n SPDX-License-Identifier: Apache-2.0\n*/\n\npragma solidity ^0.8.18;\n\n/**\n * @title Uint256ArrayUtils\n * @author Set Protocol\n *\n * Utility functions to handle Uint256 Arrays\n */\nlibrary Uint256ArrayUtils {\n\n uint256 constant internal MAX_INT = 2**256 - 1;\n\n /**\n * Finds the index of the first occurrence of the given element.\n * @param A The input array to search\n * @param a The value to find\n * @return Returns (index and isIn) for the first occurrence starting from index 0\n */\n function indexOf(uint256[] memory A, uint256 a) internal pure returns (uint256, bool) {\n uint256 length = A.length;\n for (uint256 i = 0; i < length; i++) {\n if (A[i] == a) {\n return (i, true);\n }\n }\n return (MAX_INT, false);\n }\n\n /**\n * Returns the combination of the two arrays\n * @param A The first array\n * @param B The second array\n * @return Returns A extended by B\n */\n function extend(uint256[] memory A, uint256[] memory B) internal pure returns (uint256[] memory) {\n uint256 aLength = A.length;\n uint256 bLength = B.length;\n uint256[] memory newUints = new uint256[](aLength + bLength);\n for (uint256 i = 0; i < aLength; i++) {\n newUints[i] = A[i];\n }\n for (uint256 j = 0; j < bLength; j++) {\n newUints[aLength + j] = B[j];\n }\n return newUints;\n }\n\n /**\n * @param A The input array to search\n * @param a The bytes32 to remove\n */\n function removeStorage(uint256[] storage A, uint256 a)\n internal\n {\n (uint256 index, bool isIn) = indexOf(A, a);\n if (!isIn) {\n revert(\"uint256 not in array.\");\n } else {\n uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here\n if (index != lastIndex) { A[index] = A[lastIndex]; }\n A.pop();\n }\n }\n}\n" + }, + "contracts/lib/StringConversionUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.18;\n\n// Building on zk-email's StringUtils library we add the ability to handle decimals when\n// converting from string to Uint\nlibrary StringConversionUtils {\n \n /**\n * @notice Function that parses numbers returned as strings including floating point numbers. Returned floating point\n * numbers are to have the desired amount of decimal specified. If the stringified version of the floating point\n * number has more decimal places than desired then the function will revert in order to be maximally safe. If\n * the returned number has multiple floating points then the function will revert.\n *\n * Examples: _s = \"12.34\", _expectedDecimals = 6 => 12340000\n * _s = \"12.34\", _expectedDecimals = 2 => 1234\n * _s = \"12.34\", _expectedDecimals = 1 => REVERT (we never want loss of precision only addition)\n * _s = \"12.34.56\", _expectedDecimals = 6 => REVERT (Invalid number)\n *\n * @param _s String being processed\n * @param _desiredDecimals Desired amount of decimal places\n */\n function stringToUint(string memory _s, uint256 _desiredDecimals) internal pure returns (uint256) {\n return stringToUint(_s, 0x2E, _desiredDecimals);\n }\n\n function stringToUint(\n string memory _s,\n bytes1 _decimalCharacter,\n uint256 _desiredDecimals\n )\n internal\n pure\n returns (uint256)\n {\n bytes memory b = bytes(_s);\n\n uint256 result = 0;\n uint256 decimalPlaces = 0;\n\n bool decimals = false;\n for (uint256 i = 0; i < b.length; i++) {\n if (b[i] >= 0x30 && b[i] <= 0x39) {\n result = result * 10 + (uint256(uint8(b[i])) - 48);\n }\n\n if (decimals) {\n decimalPlaces++;\n }\n\n if (b[i] == _decimalCharacter) {\n require(decimals == false, \"String has multiple decimals\");\n decimals = true;\n }\n }\n\n require(decimalPlaces <= _desiredDecimals, \"String has too many decimal places\");\n return result * (10 ** (_desiredDecimals - decimalPlaces));\n }\n\n /**\n * @notice Function that returns a substring from _startIndex to _endIndex (non-inclusive).\n *\n * @param _str String being processed\n * @param _startIndex Index to start parsing from\n * @param _endIndex Index to stop parsing at (index not included in result)\n */\n function substring(string memory _str, uint _startIndex, uint _endIndex) internal pure returns (string memory ) {\n bytes memory strBytes = bytes(_str);\n bytes memory result = new bytes(_endIndex-_startIndex);\n for(uint i = _startIndex; i < _endIndex; i++) {\n result[i-_startIndex] = strBytes[i];\n }\n return string(result);\n }\n\n function replaceString(\n string memory _str,\n string memory _lookupValue,\n string memory _replaceValue\n )\n internal\n pure\n returns (string memory)\n {\n bytes memory strBytes = bytes(_str);\n bytes memory lookupBytes = bytes(_lookupValue);\n\n uint256 lookupIndex = indexOf(_str, _lookupValue);\n if (lookupIndex == type(uint256).max) {\n return _str;\n }\n\n // Split the original string into two parts: before and after the keyword\n string memory beforeKeyword = substring(_str, 0, lookupIndex);\n string memory afterKeyword = substring(_str, lookupIndex + lookupBytes.length, strBytes.length);\n \n return string.concat(beforeKeyword, _replaceValue, afterKeyword);\n }\n\n function indexOf(string memory str, string memory substr) internal pure returns (uint) {\n bytes memory strBytes = bytes(str);\n bytes memory substrBytes = bytes(substr);\n \n if (strBytes.length < substrBytes.length) return type(uint256).max;\n \n for (uint i = 0; i <= strBytes.length - substrBytes.length; i++) {\n bool found = true;\n for (uint j = 0; j < substrBytes.length; j++) {\n if (strBytes[i + j] != substrBytes[j]) {\n found = false;\n break;\n }\n }\n if (found) return i;\n }\n \n return type(uint256).max;\n }\n\n function stringComparison(string memory _a, string memory _b) internal pure returns (bool) {\n return (keccak256(abi.encodePacked(_a)) == keccak256(abi.encodePacked(_b)));\n }\n}\n" + }, + "contracts/processors/keyHashAdapters/IKeyHashAdapterV2.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.18;\n\ninterface IKeyHashAdapterV2 {\n function addMailServerKeyHash(bytes32 _mailserverKeyHash) external;\n function removeMailServerKeyHash(bytes32 _mailserverKeyHash) external;\n function getMailServerKeyHashes() external view returns (bytes32[] memory);\n function isMailServerKeyHash(bytes32 _mailserverKeyHash) external view returns (bool);\n}\n" + }, + "contracts/processors/nullifierRegistries/INullifierRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.18;\n\ninterface INullifierRegistry {\n function addNullifier(bytes32 _nullifier) external;\n function isNullified(bytes32 _nullifier) external view returns(bool);\n}\n" + }, + "contracts/processors/TLSBaseProcessor.sol": { + "content": "//SPDX-License-Identifier: MIT\n\nimport { ECDSA } from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { SignatureChecker } from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\n\nimport { INullifierRegistry } from \"./nullifierRegistries/INullifierRegistry.sol\";\n\npragma solidity ^0.8.18;\n\ncontract TLSBaseProcessor is Ownable {\n\n using SignatureChecker for address;\n using ECDSA for bytes32;\n\n /* ============ Modifiers ============ */\n modifier onlyRamp() {\n require(msg.sender == ramp, \"Only Ramp can call this function\");\n _;\n }\n\n /* ============ State Variables ============ */\n address public immutable ramp;\n string public endpoint;\n string public host;\n\n INullifierRegistry public nullifierRegistry;\n uint256 public timestampBuffer;\n\n /* ============ Constructor ============ */\n constructor(\n address _ramp,\n INullifierRegistry _nullifierRegistry,\n uint256 _timestampBuffer,\n string memory _endpoint,\n string memory _host\n )\n Ownable()\n {\n ramp = _ramp;\n endpoint = _endpoint;\n host = _host;\n\n nullifierRegistry = _nullifierRegistry;\n timestampBuffer = _timestampBuffer;\n }\n\n /* ============ External Functions ============ */\n\n /**\n * @notice ONLY OWNER: Sets the timestamp buffer for validated TLS calls. This is the amount of time in seconds\n * that the timestamp can be off by and still be considered valid. Necessary to build in flexibility with L2\n * timestamps.\n *\n * @param _timestampBuffer The timestamp buffer for validated TLS calls\n */\n function setTimestampBuffer(uint256 _timestampBuffer) external onlyOwner {\n timestampBuffer = _timestampBuffer;\n }\n\n /* ============ Internal Functions ============ */\n\n function _validateTLSEndpoint(\n string memory _expectedEndpoint,\n string memory _passedEndpoint\n )\n internal\n pure\n {\n require(\n keccak256(abi.encode(_expectedEndpoint)) == keccak256(abi.encode(_passedEndpoint)),\n \"Endpoint does not match expected\"\n );\n }\n\n function _validateTLSHost(\n string memory _expectedHost,\n string memory _passedHost\n )\n internal\n pure\n {\n require(\n keccak256(abi.encode(_expectedHost)) == keccak256(abi.encode(_passedHost)),\n \"Host does not match expected\"\n );\n }\n\n function _validateAndAddNullifier(bytes32 _nullifier) internal {\n require(!nullifierRegistry.isNullified(_nullifier), \"Nullifier has already been used\");\n nullifierRegistry.addNullifier(_nullifier);\n }\n\n function _isValidVerifierSignature(\n bytes memory _message,\n bytes memory _signature,\n address _verifier\n )\n internal\n view\n returns(bool)\n {\n bytes32 verifierPayload = keccak256(_message).toEthSignedMessageHash();\n\n return _verifier.isValidSignatureNow(verifierPayload, _signature);\n }\n}\n" + }, + "contracts/ramps/wise/interfaces/IWiseAccountRegistrationProcessor.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.18;\n\ninterface IWiseAccountRegistrationProcessor {\n\n struct RegistrationData {\n string endpoint;\n string host;\n string profileId;\n string wiseTagHash;\n address userAddress;\n }\n\n struct RegistrationProof {\n RegistrationData public_values;\n bytes proof;\n }\n\n function processProof(\n RegistrationProof calldata _proof\n )\n external\n returns (bytes32, bytes32);\n}\n" + }, + "contracts/ramps/wise/interfaces/IWiseAccountRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.18;\n\ninterface IWiseAccountRegistry {\n\n // Each Account is tied to a Wise ID and is represented by an Ethereum address.\n struct AccountInfo {\n bytes32 accountId; // User's Wise account ID\n bytes32 offRampId; // Multi-currency account ID to receive funds\n bytes32 wiseTagHash; // Hash of user's wise tag account stored on register. Used to verify offramper's wise tag\n }\n\n function getAccountInfo(address _account) external view returns (AccountInfo memory);\n function getAccountId(address _account) external view returns (bytes32);\n\n function isRegisteredUser(address _account) external view returns (bool);\n \n function isAllowedUser(address _account, bytes32 _deniedUser) external view returns (bool);\n}\n" + }, + "contracts/ramps/wise/interfaces/IWiseOffRamperRegistrationProcessor.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.18;\n\ninterface IWiseOffRamperRegistrationProcessor {\n\n struct OffRamperRegistrationData {\n string endpoint;\n string host;\n string profileId;\n string mcAccountId;\n }\n\n struct OffRamperRegistrationProof {\n OffRamperRegistrationData public_values;\n bytes proof;\n }\n\n function processProof(\n OffRamperRegistrationProof calldata _proof\n )\n external\n returns (bytes32, bytes32);\n}\n" + }, + "contracts/ramps/wise/interfaces/IWiseSendProcessor.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.18;\n\ninterface IWiseSendProcessor {\n\n struct SendData {\n string endpoint;\n string host;\n string transferId;\n string senderId;\n string recipientId;\n string amount;\n string currencyId;\n string status;\n string timestamp;\n uint256 intentHash;\n }\n\n struct SendProof {\n SendData public_values;\n bytes proof;\n }\n\n function processProof(\n SendProof calldata _proof,\n address _verifierSigningKey\n )\n external\n returns(uint256, uint256, bytes32, bytes32);\n}\n" + }, + "contracts/ramps/wise/mocks/WiseAccountRegistrationProcessorMock.sol": { + "content": "//SPDX-License-Identifier: MIT\n\nimport { IWiseAccountRegistrationProcessor } from \"../interfaces/IWiseAccountRegistrationProcessor.sol\";\nimport { StringConversionUtils } from \"../../../lib/StringConversionUtils.sol\";\n\npragma solidity ^0.8.18;\n\ncontract WiseAccountRegistrationProcessorMock is IWiseAccountRegistrationProcessor {\n\n using StringConversionUtils for string;\n\n /* ============ Constructor ============ */\n constructor() {}\n\n /* ============ External View Functions ============ */\n function processProof(\n RegistrationProof calldata _proof\n )\n public\n pure\n override\n returns(bytes32 onRampId, bytes32 wiseTagHash)\n {\n return(\n bytes32(_proof.public_values.profileId.stringToUint(0)),\n bytes32(_proof.public_values.wiseTagHash.stringToUint(0))\n );\n }\n}\n" + }, + "contracts/ramps/wise/mocks/WiseOffRamperRegistrationProcessorMock.sol": { + "content": "//SPDX-License-Identifier: MIT\n\nimport { IWiseOffRamperRegistrationProcessor } from \"../interfaces/IWiseOffRamperRegistrationProcessor.sol\";\nimport { StringConversionUtils } from \"../../../lib/StringConversionUtils.sol\";\n\npragma solidity ^0.8.18;\n\ncontract WiseOffRamperRegistrationProcessorMock is IWiseOffRamperRegistrationProcessor {\n\n using StringConversionUtils for string;\n\n /* ============ Constructor ============ */\n constructor() {}\n\n /* ============ External View Functions ============ */\n function processProof(\n OffRamperRegistrationProof calldata _proof\n )\n public\n pure\n override\n returns(bytes32 onRampId, bytes32 wiseTagHash)\n {\n return(\n bytes32(_proof.public_values.profileId.stringToUint(0)),\n bytes32(_proof.public_values.mcAccountId.stringToUint(0))\n );\n }\n}\n" + }, + "contracts/ramps/wise/mocks/WiseSendProcessorMock.sol": { + "content": "//SPDX-License-Identifier: MIT\n\nimport { IWiseSendProcessor } from \"../interfaces/IWiseSendProcessor.sol\";\nimport { StringConversionUtils } from \"../../../lib/StringConversionUtils.sol\";\n\npragma solidity ^0.8.18;\n\ncontract WiseSendProcessorMock is IWiseSendProcessor {\n\n using StringConversionUtils for string;\n\n /* ============ Constructor ============ */\n constructor() {}\n\n /* ============ External View Functions ============ */\n function processProof(\n SendProof calldata _proof,\n address /*_verifierSigningKey*/\n )\n public\n pure\n override\n returns(\n uint256 amount,\n uint256 timestamp,\n bytes32 offRamperIdHash,\n bytes32 currencyId\n )\n {\n return(\n _proof.public_values.amount.stringToUint(6),\n _proof.public_values.timestamp.stringToUint(0),\n bytes32(_proof.public_values.recipientId.stringToUint(0)),\n keccak256(abi.encodePacked(_proof.public_values.currencyId))\n );\n }\n}\n" + }, + "contracts/ramps/wise/WiseAccountRegistrationProcessor.sol": { + "content": "//SPDX-License-Identifier: MIT\n\nimport { ECDSA } from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport { SignatureChecker } from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\n\nimport { INullifierRegistry } from \"../../processors/nullifierRegistries/INullifierRegistry.sol\";\nimport { IWiseAccountRegistrationProcessor } from \"./interfaces/IWiseAccountRegistrationProcessor.sol\";\nimport { StringConversionUtils } from \"../../lib/StringConversionUtils.sol\";\nimport { TLSBaseProcessor } from \"../../processors/TLSBaseProcessor.sol\";\n\npragma solidity ^0.8.18;\n\ncontract WiseAccountRegistrationProcessor is IWiseAccountRegistrationProcessor, TLSBaseProcessor {\n\n using ECDSA for bytes32;\n using SignatureChecker for address;\n using StringConversionUtils for string;\n \n /* ============ Events ============ */\n event VerifierSigningKeySet(address _verifierSigningKey);\n \n /* ============ Public Variables ============ */\n address public verifierSigningKey;\n \n /* ============ Constructor ============ */\n constructor(\n address _ramp,\n address _verifierSigningKey,\n INullifierRegistry _nullifierRegistry,\n uint256 _timestampBuffer,\n string memory _endpoint,\n string memory _host\n )\n TLSBaseProcessor(\n _ramp,\n _nullifierRegistry,\n _timestampBuffer,\n _endpoint,\n _host\n )\n {\n verifierSigningKey = _verifierSigningKey;\n }\n\n /* ============ External Functions ============ */\n\n function processProof(\n IWiseAccountRegistrationProcessor.RegistrationProof calldata _proof\n )\n public\n override\n onlyRamp\n returns(bytes32 onRampId, bytes32 wiseTagHash)\n {\n _validateProof(_proof.public_values, _proof.proof);\n\n _validateTLSEndpoint(endpoint, _proof.public_values.endpoint);\n _validateTLSHost(host, _proof.public_values.host);\n\n _validateAndAddNullifier(keccak256(abi.encode(_proof.public_values.userAddress, _proof.public_values.profileId)));\n\n onRampId = bytes32(_proof.public_values.profileId.stringToUint(0));\n wiseTagHash = bytes32(_proof.public_values.wiseTagHash.stringToUint(0));\n }\n\n /* ============ External Admin Functions ============ */\n\n function setVerifierSigningKey(address _verifierSigningKey) external onlyOwner {\n verifierSigningKey = _verifierSigningKey;\n\n emit VerifierSigningKeySet(_verifierSigningKey);\n }\n\n /* ============ View Functions ============ */\n\n function verifyProof(\n IWiseAccountRegistrationProcessor.RegistrationData memory _publicValues,\n bytes memory _proof\n )\n public\n view\n returns(bool)\n {\n bytes memory encodedMessage = abi.encode(\n _publicValues.endpoint,\n _publicValues.host,\n _publicValues.profileId,\n _publicValues.wiseTagHash,\n _publicValues.userAddress\n );\n return _isValidVerifierSignature(encodedMessage, _proof, verifierSigningKey);\n }\n \n /* ============ Internal Functions ============ */\n\n function _validateProof(\n IWiseAccountRegistrationProcessor.RegistrationData memory _publicValues, \n bytes memory _proof\n )\n internal\n view\n { \n require(\n verifyProof(_publicValues, _proof),\n \"Invalid signature from verifier\"\n );\n }\n}\n" + }, + "contracts/ramps/wise/WiseAccountRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport { Bytes32ArrayUtils } from \"../../external/Bytes32ArrayUtils.sol\";\nimport { Uint256ArrayUtils } from \"../../external/Uint256ArrayUtils.sol\";\n\nimport { IWiseAccountRegistrationProcessor } from \"./interfaces/IWiseAccountRegistrationProcessor.sol\";\nimport { IWiseAccountRegistry } from \"./interfaces/IWiseAccountRegistry.sol\";\nimport { IWiseOffRamperRegistrationProcessor } from \"./interfaces/IWiseOffRamperRegistrationProcessor.sol\";\n\npragma solidity ^0.8.18;\n\ncontract WiseAccountRegistry is IWiseAccountRegistry, Ownable {\n using Bytes32ArrayUtils for bytes32[];\n using Uint256ArrayUtils for uint256[];\n\n /* ============ Events ============ */\n event AccountRegistered(address indexed accountOwner, bytes32 indexed accountId, bytes32 indexed wiseTagHash);\n event OffRamperRegistered(address indexed accountOwner, bytes32 indexed accountId, bytes32 indexed offRampId);\n\n event UserAddedToDenylist(bytes32 listOwner, bytes32 deniedUser);\n event UserRemovedFromDenylist(bytes32 listOwner, bytes32 approvedUser);\n\n event AllowlistEnabled(bytes32 listOwner);\n event UserAddedToAllowlist(bytes32 indexed listOwner, bytes32 allowedUser);\n event UserRemovedFromAllowlist(bytes32 indexed listOwner, bytes32 allowedUser);\n\n event NewAccountRegistrationProcessorSet(address registrationProcessor);\n event NewOffRamperRegistrationProcessorSet(address registrationProcessor);\n\n /* ============ Structs ============ */\n\n struct DenyList {\n bytes32[] deniedUsers; // Array of accountIds that are denied from taking depositors liquidity\n mapping(bytes32 => bool) isDenied; // Mapping of accountId to boolean indicating if the user is denied\n }\n\n struct AllowList {\n bool isEnabled; // Boolean indicating if the allowlist is enabled\n bytes32[] allowedUsers; // Array of accountIds that are allowed from taking depositors liquidity\n mapping(bytes32 => bool) isAllowed; // Mapping of accountId to boolean indicating if the user is allowed\n }\n\n /* ============ Modifiers ============ */\n modifier onlyRegisteredUser() {\n require(isRegisteredUser(msg.sender), \"Caller must be registered user\");\n _;\n }\n\n /* ============ State Variables ============ */\n IWiseAccountRegistrationProcessor public accountRegistrationProcessor; // Address of Account registration processor contract\n IWiseOffRamperRegistrationProcessor public offRamperRegistrationProcessor; // Address of Off-ramper registration processor contract\n\n bool public isInitialized; // Indicates if contract has been initialized\n\n mapping(address => AccountInfo) internal accounts; // Mapping of Ethereum accounts to their account information (IDs and deposits)\n mapping(bytes32 => DenyList) internal denyList; // Mapping of accountId to denylist\n mapping(bytes32 => AllowList) internal allowList; // Mapping of accountId to allow list\n\n /* ============ Constructor ============ */\n constructor(\n address _owner\n )\n Ownable()\n {\n transferOwnership(_owner);\n }\n\n /* ============ External Functions ============ */\n\n /**\n * @notice Initialize Ramp with the addresses of the Processors\n *\n * @param _accountRegistrationProcessor Account Registration processor address\n * @param _offRamperRegistrationProcessor Off-ramper Registration processor address\n */\n function initialize(\n IWiseAccountRegistrationProcessor _accountRegistrationProcessor,\n IWiseOffRamperRegistrationProcessor _offRamperRegistrationProcessor\n )\n external\n onlyOwner\n {\n require(!isInitialized, \"Already initialized\");\n\n accountRegistrationProcessor = _accountRegistrationProcessor;\n offRamperRegistrationProcessor = _offRamperRegistrationProcessor;\n\n isInitialized = true;\n }\n\n /**\n * @notice Registers a new account by pulling the profileId from the proof and assigning the account owner to the\n * sender of the transaction.\n *\n * @param _proof Registration proof consisting of unredacted data being notarized and a signature\n */\n function register(\n IWiseAccountRegistrationProcessor.RegistrationProof calldata _proof\n )\n external\n {\n require(msg.sender == _proof.public_values.userAddress, \"Caller must be address specified in proof\");\n require(accounts[msg.sender].accountId == bytes32(0), \"Account already associated with accountId\");\n (\n bytes32 accountId,\n bytes32 wiseTagHash\n ) = _verifyRegistrationProof(_proof);\n\n accounts[msg.sender].accountId = accountId;\n accounts[msg.sender].wiseTagHash = wiseTagHash;\n\n emit AccountRegistered(msg.sender, accountId, wiseTagHash);\n }\n\n /**\n * @notice Registers an account for off-ramping by pulling the multi-currency account id from the proof and assigning\n * the account owner to the sender of the transaction.\n *\n * @param _proof Registration proof consisting of unredacted data being notarized and a signature\n */\n function registerAsOffRamper(\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof calldata _proof\n )\n external\n onlyRegisteredUser\n {\n require(accounts[msg.sender].offRampId == bytes32(0), \"Account already associated with offRampId\");\n (\n bytes32 accountId,\n bytes32 offRampId\n ) = _verifyOffRamperRegistrationProof(_proof);\n\n accounts[msg.sender].offRampId = offRampId;\n\n emit OffRamperRegistered(msg.sender, accountId, offRampId);\n }\n\n /**\n * @notice Adds an accountId to a depositor's deny list. If an address associated with the banned accountId attempts to\n * signal an intent on the user's deposit they will be denied.\n *\n * @param _deniedUser accountId being banned\n */\n function addAccountToDenylist(bytes32 _deniedUser) external onlyRegisteredUser {\n bytes32 denyingUser = accounts[msg.sender].accountId;\n\n require(!denyList[denyingUser].isDenied[_deniedUser], \"User already on denylist\");\n\n denyList[denyingUser].isDenied[_deniedUser] = true;\n denyList[denyingUser].deniedUsers.push(_deniedUser);\n\n emit UserAddedToDenylist(denyingUser, _deniedUser);\n }\n\n /**\n * @notice Removes an accountId from a depositor's deny list.\n *\n * @param _approvedUser accountId being approved\n */\n function removeAccountFromDenylist(bytes32 _approvedUser) external onlyRegisteredUser {\n bytes32 approvingUser = accounts[msg.sender].accountId;\n\n require(denyList[approvingUser].isDenied[_approvedUser], \"User not on denylist\");\n\n denyList[approvingUser].isDenied[_approvedUser] = false;\n denyList[approvingUser].deniedUsers.removeStorage(_approvedUser);\n\n emit UserRemovedFromDenylist(approvingUser, _approvedUser);\n }\n\n /**\n * @notice Enables allow list for user, only users on the allow list will be able to signal intents on the user's deposit.\n */\n function enableAllowlist() external onlyRegisteredUser {\n bytes32 allowingUser = accounts[msg.sender].accountId;\n\n require(!allowList[allowingUser].isEnabled, \"Allow list already enabled\");\n\n allowList[allowingUser].isEnabled = true;\n\n emit AllowlistEnabled(allowingUser);\n }\n\n /**\n * @notice Adds passed accountIds to a depositor's allow list. All addresses associated with the allowed accountIds will\n * be able to signal intents on the user's deposit.\n *\n * @param _allowedUsers List of accountIds allowed to signal intents on the user's deposit\n */\n function addAccountsToAllowlist(bytes32[] memory _allowedUsers) external onlyRegisteredUser {\n bytes32 allowingUser = accounts[msg.sender].accountId;\n\n for(uint256 i = 0; i < _allowedUsers.length; i++) {\n bytes32 allowedUser = _allowedUsers[i];\n\n require(!allowList[allowingUser].isAllowed[allowedUser], \"User already on allowlist\");\n\n allowList[allowingUser].isAllowed[allowedUser] = true;\n allowList[allowingUser].allowedUsers.push(allowedUser);\n\n emit UserAddedToAllowlist(allowingUser, allowedUser);\n }\n }\n\n /**\n * @notice Removes an passed accountId's from allow list. If allow list is enabled only users on the allow list will be\n * able to signal intents on the user's deposit.\n *\n * @param _disallowedUsers List of accountIds being approved\n */\n function removeAccountsFromAllowlist(bytes32[] memory _disallowedUsers) external onlyRegisteredUser {\n bytes32 disallowingUser = accounts[msg.sender].accountId;\n\n for(uint256 i = 0; i < _disallowedUsers.length; i++) {\n bytes32 disallowedUser = _disallowedUsers[i];\n\n require(allowList[disallowingUser].isAllowed[disallowedUser], \"User not on allowlist\");\n\n allowList[disallowingUser].isAllowed[disallowedUser] = false;\n allowList[disallowingUser].allowedUsers.removeStorage(disallowedUser);\n\n emit UserRemovedFromAllowlist(disallowingUser, disallowedUser);\n }\n }\n\n /* ============ Governance Functions ============ */\n\n /**\n * @notice GOVERNANCE ONLY: Updates the account registration processor address used for validating and interpreting tls proofs.\n *\n * @param _registrationProcessor New registration proccesor address\n */\n function setAccountRegistrationProcessor(IWiseAccountRegistrationProcessor _registrationProcessor) external onlyOwner {\n accountRegistrationProcessor = _registrationProcessor;\n emit NewAccountRegistrationProcessorSet(address(_registrationProcessor));\n }\n\n /**\n * @notice GOVERNANCE ONLY: Updates the off ramper registration processor address used for validating and interpreting tls proofs.\n *\n * @param _registrationProcessor New registration proccesor address\n */\n function setOffRamperRegistrationProcessor(IWiseOffRamperRegistrationProcessor _registrationProcessor) external onlyOwner {\n offRamperRegistrationProcessor = _registrationProcessor;\n emit NewOffRamperRegistrationProcessorSet(address(_registrationProcessor));\n }\n\n /* ============ External View Functions ============ */\n\n function getAccountInfo(address _account) external view returns (AccountInfo memory) {\n return accounts[_account];\n }\n\n function getAccountId(address _account) public view returns (bytes32) {\n return accounts[_account].accountId;\n }\n\n function isRegisteredUser(address _account) public view returns (bool) {\n return getAccountId(_account) != bytes32(0);\n }\n\n function getDeniedUsers(address _account) external view returns (bytes32[] memory) {\n return denyList[getAccountId(_account)].deniedUsers;\n }\n\n function isDeniedUser(address _account, bytes32 _deniedUser) external view returns (bool) {\n return denyList[getAccountId(_account)].isDenied[_deniedUser];\n }\n\n function isAllowlistEnabled(address _account) external view returns (bool) {\n return allowList[getAccountId(_account)].isEnabled;\n }\n\n function getAllowedUsers(address _account) external view returns (bytes32[] memory) {\n return allowList[getAccountId(_account)].allowedUsers;\n }\n\n function isAllowedUser(address _account, bytes32 _allowedUser) external view returns (bool) {\n bytes32 allowingUser = getAccountId(_account);\n\n // Deny list overrides, if user on deny list then they are not allowed\n if(denyList[allowingUser].isDenied[_allowedUser]) { return false; }\n\n // Check if allow list is enabled, if so return status of user, else return true\n return allowList[allowingUser].isEnabled ? allowList[allowingUser].isAllowed[_allowedUser] : true;\n }\n \n /* ============ Internal Functions ============ */\n\n /**\n * @notice Validate the user has an Wise account, we do not nullify this email since it can be reused to register under\n * different addresses.\n */\n function _verifyRegistrationProof(\n IWiseAccountRegistrationProcessor.RegistrationProof calldata _proof\n )\n internal\n returns(bytes32 accountId, bytes32 wiseTagHash)\n {\n (\n accountId,\n wiseTagHash\n ) = accountRegistrationProcessor.processProof(_proof);\n }\n\n /**\n * @notice Validate the user has an Wise account, we do not nullify this email since it can be reused to register under\n * different addresses.\n */\n function _verifyOffRamperRegistrationProof(\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof calldata _proof\n )\n internal\n returns(bytes32 accountId, bytes32 offRampId)\n {\n (\n accountId,\n offRampId\n ) = offRamperRegistrationProcessor.processProof(_proof);\n\n require(accountId == accounts[msg.sender].accountId, \"AccountId does not match\");\n }\n}\n" + }, + "contracts/ramps/wise/WiseOffRamperRegistrationProcessor.sol": { + "content": "//SPDX-License-Identifier: MIT\n\nimport { INullifierRegistry } from \"../../processors/nullifierRegistries/INullifierRegistry.sol\";\nimport { IWiseOffRamperRegistrationProcessor } from \"./interfaces/IWiseOffRamperRegistrationProcessor.sol\";\nimport { StringConversionUtils } from \"../../lib/StringConversionUtils.sol\";\nimport { TLSBaseProcessor } from \"../../processors/TLSBaseProcessor.sol\";\n\npragma solidity ^0.8.18;\n\ncontract WiseOffRamperRegistrationProcessor is IWiseOffRamperRegistrationProcessor, TLSBaseProcessor {\n\n using StringConversionUtils for string;\n \n /* ============ Events ============ */\n event VerifierSigningKeySet(address _verifierSigningKey);\n \n /* ============ Public Variables ============ */\n address public verifierSigningKey;\n \n /* ============ Constructor ============ */\n constructor(\n address _ramp,\n address _verifierSigningKey,\n INullifierRegistry _nullifierRegistry,\n uint256 _timestampBuffer,\n string memory _endpoint,\n string memory _host\n )\n TLSBaseProcessor(\n _ramp,\n _nullifierRegistry,\n _timestampBuffer,\n _endpoint,\n _host\n )\n {\n verifierSigningKey = _verifierSigningKey;\n }\n\n /* ============ External Functions ============ */\n\n function processProof(\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationProof calldata _proof\n )\n public\n view\n override\n onlyRamp\n returns(bytes32 onRampId, bytes32 offRampId)\n {\n _validateProof(_proof.public_values, _proof.proof);\n\n _validateTLSEndpoint(endpoint.replaceString(\"*\", _proof.public_values.profileId), _proof.public_values.endpoint);\n _validateTLSHost(host, _proof.public_values.host);\n\n onRampId = bytes32(_proof.public_values.profileId.stringToUint(0));\n offRampId = bytes32(_proof.public_values.mcAccountId.stringToUint(0));\n }\n\n /* ============ External Admin Functions ============ */\n\n function setVerifierSigningKey(address _verifierSigningKey) external onlyOwner {\n verifierSigningKey = _verifierSigningKey;\n\n emit VerifierSigningKeySet(_verifierSigningKey);\n }\n\n /* ============ View Functions ============ */\n\n function verifyProof(\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationData memory _publicValues, \n bytes memory _proof\n )\n internal\n view\n returns(bool)\n { \n bytes memory encodedMessage = abi.encode(_publicValues.endpoint, _publicValues.host, _publicValues.profileId, _publicValues.mcAccountId);\n return _isValidVerifierSignature(encodedMessage, _proof, verifierSigningKey);\n }\n\n /* ============ Internal Functions ============ */\n\n function _validateProof(\n IWiseOffRamperRegistrationProcessor.OffRamperRegistrationData memory _publicValues, \n bytes memory _proof\n )\n internal\n view\n { \n require(\n verifyProof(_publicValues, _proof),\n \"Invalid signature from verifier\"\n );\n }\n}\n" + }, + "contracts/ramps/wise/WiseRamp.sol": { + "content": "//SPDX-License-Identifier: MIT\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport { Bytes32ArrayUtils } from \"../../external/Bytes32ArrayUtils.sol\";\nimport { Uint256ArrayUtils } from \"../../external/Uint256ArrayUtils.sol\";\n\nimport { IWiseAccountRegistry } from \"./interfaces/IWiseAccountRegistry.sol\";\nimport { IWiseSendProcessor } from \"./interfaces/IWiseSendProcessor.sol\";\n\npragma solidity ^0.8.18;\n\ncontract WiseRamp is Ownable {\n\n using Bytes32ArrayUtils for bytes32[];\n using Uint256ArrayUtils for uint256[];\n\n /* ============ Events ============ */\n event DepositReceived(\n uint256 indexed depositId,\n bytes32 indexed offRampId,\n bytes32 indexed currencyId,\n uint256 amount,\n uint256 conversionRate\n );\n event IntentSignaled(\n bytes32 indexed intentHash,\n uint256 indexed depositId,\n bytes32 indexed accountId,\n address to,\n uint256 amount,\n uint256 timestamp\n );\n\n event IntentPruned(\n bytes32 indexed intentHash,\n uint256 indexed depositId\n );\n event IntentFulfilled(\n bytes32 indexed intentHash,\n uint256 indexed depositId,\n address indexed onRamper,\n address to,\n uint256 amount,\n uint256 feeAmount\n );\n event DepositWithdrawn(\n uint256 indexed depositId,\n address indexed depositor,\n uint256 amount\n );\n\n event DepositClosed(uint256 depositId, address depositor);\n event MinDepositAmountSet(uint256 minDepositAmount);\n event MaxOnRampAmountSet(uint256 maxOnRampAmount);\n event IntentExpirationPeriodSet(uint256 intentExpirationPeriod);\n event OnRampCooldownPeriodSet(uint256 onRampCooldownPeriod);\n event SustainabilityFeeUpdated(uint256 fee);\n event SustainabilityFeeRecipientUpdated(address feeRecipient);\n event NewSendProcessorSet(address sendProcessor);\n\n /* ============ Structs ============ */\n\n struct Deposit {\n address depositor;\n string wiseTag;\n address verifierSigningKey; // Public key of the verifier depositor wants to sign the TLS proof\n uint256 depositAmount; // Amount of USDC deposited\n bytes32 receiveCurrencyId; // Id of the currency to be received off-chain (bytes32(Wise currency code))\n uint256 remainingDeposits; // Amount of remaining deposited liquidity\n uint256 outstandingIntentAmount; // Amount of outstanding intents (may include expired intents)\n uint256 conversionRate; // Conversion required by off-ramper between USDC/USD\n bytes32[] intentHashes; // Array of hashes of all open intents (may include some expired if not pruned)\n }\n\n struct DepositWithAvailableLiquidity {\n uint256 depositId; // ID of the deposit\n bytes32 depositorId; // Depositor's offRampId \n Deposit deposit; // Deposit struct\n uint256 availableLiquidity; // Amount of liquidity available to signal intents (net of expired intents)\n }\n\n struct Intent {\n address onRamper; // On-ramper's address\n address to; // Address to forward funds to (can be same as onRamper)\n uint256 deposit; // ID of the deposit the intent is signaling on\n uint256 amount; // Amount of USDC the on-ramper signals intent for on-chain\n uint256 intentTimestamp; // Timestamp of when the intent was signaled\n }\n\n struct IntentWithOnRamperId {\n bytes32 intentHash; // Intent hash\n Intent intent; // Intent struct\n bytes32 onRamperId; // onRamper's onRamperId\n }\n\n // A Global Account is defined as an account represented by one accountId. This is used to enforce limitations on actions across\n // all Ethereum addresses that are associated with that accountId. In this case we use it to enforce a cooldown period between on ramps,\n // restrict each Wise account to one outstanding intent at a time, and to enforce deny lists.\n struct GlobalAccountInfo {\n bytes32 currentIntentHash; // Hash of the current open intent (if exists)\n uint256 lastOnrampTimestamp; // Timestamp of the last on-ramp transaction used to check if cooldown period elapsed\n uint256[] deposits; // Array of open account deposits\n }\n\n /* ============ Modifiers ============ */\n modifier onlyRegisteredUser() {\n require(accountRegistry.isRegisteredUser(msg.sender), \"Caller must be registered user\");\n _;\n }\n\n /* ============ Constants ============ */\n uint256 internal constant PRECISE_UNIT = 1e18;\n uint256 internal constant MAX_DEPOSITS = 5; // An account can only have max 5 different deposit parameterizations to prevent locking funds\n uint256 constant CIRCOM_PRIME_FIELD = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n uint256 constant MAX_SUSTAINABILITY_FEE = 5e16; // 5% max sustainability fee\n \n /* ============ State Variables ============ */\n IERC20 public immutable usdc; // USDC token contract\n IWiseAccountRegistry public accountRegistry; // Account Registry contract for Wise\n IWiseSendProcessor public sendProcessor; // Address of send processor contract\n\n bool public isInitialized; // Indicates if contract has been initialized\n\n mapping(bytes32 => GlobalAccountInfo) internal globalAccount; // Mapping of onRamp ID to information used to enforce actions across Ethereum accounts\n mapping(uint256 => Deposit) public deposits; // Mapping of depositIds to deposit structs\n mapping(bytes32 => Intent) public intents; // Mapping of intentHashes to intent structs\n\n uint256 public minDepositAmount; // Minimum amount of USDC that can be deposited\n uint256 public maxOnRampAmount; // Maximum amount of USDC that can be on-ramped in a single transaction\n uint256 public onRampCooldownPeriod; // Time period that must elapse between completing an on-ramp and signaling a new intent\n uint256 public intentExpirationPeriod; // Time period after which an intent can be pruned from the system\n uint256 public sustainabilityFee; // Fee charged to on-rampers in preciseUnits (1e16 = 1%)\n address public sustainabilityFeeRecipient; // Address that receives the sustainability fee\n\n uint256 public depositCounter; // Counter for depositIds\n\n /* ============ Constructor ============ */\n constructor(\n address _owner,\n IERC20 _usdc,\n uint256 _minDepositAmount,\n uint256 _maxOnRampAmount,\n uint256 _intentExpirationPeriod,\n uint256 _onRampCooldownPeriod,\n uint256 _sustainabilityFee,\n address _sustainabilityFeeRecipient\n )\n Ownable()\n {\n usdc = _usdc;\n minDepositAmount = _minDepositAmount;\n maxOnRampAmount = _maxOnRampAmount;\n intentExpirationPeriod = _intentExpirationPeriod;\n onRampCooldownPeriod = _onRampCooldownPeriod;\n sustainabilityFee = _sustainabilityFee;\n sustainabilityFeeRecipient = _sustainabilityFeeRecipient;\n\n transferOwnership(_owner);\n }\n\n /* ============ External Functions ============ */\n\n /**\n * @notice Initialize Ramp with the addresses of the Processors\n *\n * @param _accountRegistry Account Registry contract for Wise\n * @param _sendProcessor Send processor address\n */\n function initialize(\n IWiseAccountRegistry _accountRegistry,\n IWiseSendProcessor _sendProcessor\n )\n external\n onlyOwner\n {\n require(!isInitialized, \"Already initialized\");\n\n accountRegistry = _accountRegistry;\n sendProcessor = _sendProcessor;\n\n isInitialized = true;\n }\n\n /**\n * @notice Generates a deposit entry for off-rampers that can then be fulfilled by an on-ramper. This function will not add to\n * previous deposits. Every deposit has it's own unique identifier. User must approve the contract to transfer the deposit amount\n * of USDC.\n *\n * @param _wiseTag Depositor's Wise tag to receive payments\n * @param _receiveCurrencyId Id of the currency to be received off-chain\n * @param _depositAmount The amount of USDC to off-ramp\n * @param _receiveAmount The amount of USD to receive\n * @param _verifierSigningKey Public key of the verifier depositor wants to sign the TLS proof\n */\n function offRamp(\n string calldata _wiseTag,\n bytes32 _receiveCurrencyId,\n uint256 _depositAmount,\n uint256 _receiveAmount,\n address _verifierSigningKey\n )\n external\n onlyRegisteredUser\n {\n IWiseAccountRegistry.AccountInfo memory account = accountRegistry.getAccountInfo(msg.sender);\n GlobalAccountInfo storage globalAccountInfo = globalAccount[account.accountId];\n\n require(account.offRampId != bytes32(0), \"Must be registered as off ramper\");\n require(keccak256(abi.encode(_wiseTag)) == account.wiseTagHash, \"Wise tag does not match registered wise tag\");\n require(globalAccountInfo.deposits.length < MAX_DEPOSITS, \"Maximum deposit amount reached\");\n require(_depositAmount >= minDepositAmount, \"Deposit amount must be greater than min deposit amount\");\n require(_receiveAmount > 0, \"Receive amount must be greater than 0\");\n\n uint256 conversionRate = (_depositAmount * PRECISE_UNIT) / _receiveAmount;\n uint256 depositId = depositCounter++;\n\n globalAccountInfo.deposits.push(depositId);\n\n deposits[depositId] = Deposit({\n depositor: msg.sender,\n wiseTag: _wiseTag,\n receiveCurrencyId: _receiveCurrencyId,\n depositAmount: _depositAmount,\n remainingDeposits: _depositAmount,\n outstandingIntentAmount: 0,\n conversionRate: conversionRate,\n intentHashes: new bytes32[](0),\n verifierSigningKey: _verifierSigningKey\n });\n\n usdc.transferFrom(msg.sender, address(this), _depositAmount);\n\n emit DepositReceived(depositId, account.accountId, _receiveCurrencyId, _depositAmount, conversionRate);\n }\n\n /**\n * @notice Signals intent to pay the depositor defined in the _depositId the _amount * deposit conversionRate off-chain\n * in order to unlock _amount of funds on-chain. Each user can only have one outstanding intent at a time regardless of\n * address (tracked using accountId). Caller must not be on the depositor's deny list. If there are prunable intents then\n * they will be deleted from the deposit to be able to maintain state hygiene.\n *\n * @param _depositId The ID of the deposit the on-ramper intends to use for \n * @param _amount The amount of USDC the user wants to on-ramp\n * @param _to Address to forward funds to (can be same as onRamper)\n */\n function signalIntent(uint256 _depositId, uint256 _amount, address _to) external onlyRegisteredUser {\n bytes32 onRamperId = accountRegistry.getAccountId(msg.sender);\n Deposit storage deposit = deposits[_depositId];\n\n // Caller validity checks\n require(accountRegistry.isAllowedUser(deposit.depositor, onRamperId), \"Onramper on depositor's denylist\");\n require(\n globalAccount[onRamperId].lastOnrampTimestamp + onRampCooldownPeriod <= block.timestamp,\n \"On ramp cool down period not elapsed\"\n );\n require(globalAccount[onRamperId].currentIntentHash == bytes32(0), \"Intent still outstanding\");\n require(accountRegistry.getAccountId(deposit.depositor) != onRamperId, \"Sender cannot be the depositor\");\n\n // Intent information checks\n require(deposit.depositor != address(0), \"Deposit does not exist\");\n require(_amount > 0, \"Signaled amount must be greater than 0\");\n require(_amount <= maxOnRampAmount, \"Signaled amount must be less than max on-ramp amount\");\n require(_to != address(0), \"Cannot send to zero address\");\n\n bytes32 intentHash = _calculateIntentHash(onRamperId, _depositId);\n\n if (deposit.remainingDeposits < _amount) {\n (\n bytes32[] memory prunableIntents,\n uint256 reclaimableAmount\n ) = _getPrunableIntents(_depositId);\n\n require(deposit.remainingDeposits + reclaimableAmount >= _amount, \"Not enough liquidity\");\n\n _pruneIntents(deposit, prunableIntents);\n deposit.remainingDeposits += reclaimableAmount;\n deposit.outstandingIntentAmount -= reclaimableAmount;\n }\n\n intents[intentHash] = Intent({\n onRamper: msg.sender,\n to: _to,\n deposit: _depositId,\n amount: _amount,\n intentTimestamp: block.timestamp\n });\n\n globalAccount[onRamperId].currentIntentHash = intentHash;\n\n deposit.remainingDeposits -= _amount;\n deposit.outstandingIntentAmount += _amount;\n deposit.intentHashes.push(intentHash);\n\n emit IntentSignaled(intentHash, _depositId, onRamperId, _to, _amount, block.timestamp);\n }\n\n /**\n * @notice Only callable by the originator of the intent. Cancels an outstanding intent thus allowing user to signal a new\n * intent. Deposit state is updated to reflect the cancelled intent.\n *\n * @param _intentHash Hash of intent being cancelled\n */\n function cancelIntent(bytes32 _intentHash) external {\n Intent memory intent = intents[_intentHash];\n \n require(intent.intentTimestamp != 0, \"Intent does not exist\");\n require(\n accountRegistry.getAccountId(intent.onRamper) == accountRegistry.getAccountId(msg.sender),\n \"Sender must be the on-ramper\"\n );\n\n Deposit storage deposit = deposits[intent.deposit];\n\n _pruneIntent(deposit, _intentHash);\n\n deposit.remainingDeposits += intent.amount;\n deposit.outstandingIntentAmount -= intent.amount;\n }\n\n /**\n * @notice Anyone can submit an on-ramp transaction, even if caller isn't on-ramper. Upon submission the proof is validated,\n * intent is removed, and deposit state is updated. USDC is transferred to the on-ramper.\n *\n * @param _sendData Struct containing unredacted data from API call to Wise\n * @param _verifierSignature Signature by verifier of the unredacted data\n */\n function onRamp(\n IWiseSendProcessor.SendData calldata _sendData,\n bytes calldata _verifierSignature\n )\n external\n {\n (\n Intent memory intent,\n Deposit storage deposit,\n bytes32 intentHash\n ) = _verifyOnRampProof(_sendData, _verifierSignature);\n\n _pruneIntent(deposit, intentHash);\n\n deposit.outstandingIntentAmount -= intent.amount;\n globalAccount[accountRegistry.getAccountId(intent.onRamper)].lastOnrampTimestamp = block.timestamp;\n _closeDepositIfNecessary(intent.deposit, deposit);\n\n _transferFunds(intentHash, intent);\n }\n\n /**\n * @notice Allows off-ramper to release funds to the on-ramper in case of a failed on-ramp or because of some other arrangement\n * between the two parties. Upon submission we check to make sure the msg.sender is the depositor, the intent is removed, and \n * deposit state is updated. USDC is transferred to the on-ramper.\n *\n * @param _intentHash Hash of intent to resolve by releasing the funds\n */\n function releaseFundsToOnramper(bytes32 _intentHash) external {\n Intent memory intent = intents[_intentHash];\n Deposit storage deposit = deposits[intent.deposit];\n\n require(intent.onRamper != address(0), \"Intent does not exist\");\n require(deposit.depositor == msg.sender, \"Caller must be the depositor\");\n\n _pruneIntent(deposit, _intentHash);\n\n deposit.outstandingIntentAmount -= intent.amount;\n globalAccount[accountRegistry.getAccountId(intent.onRamper)].lastOnrampTimestamp = block.timestamp;\n _closeDepositIfNecessary(intent.deposit, deposit);\n\n _transferFunds(_intentHash, intent);\n }\n\n /**\n * @notice Caller must be the depositor for each depositId in the array, if not whole function fails. Depositor is returned all\n * remaining deposits and any outstanding intents that are expired. If an intent is not expired then those funds will not be\n * returned. Deposit will be deleted as long as there are no more outstanding intents.\n *\n * @param _depositIds Array of depositIds the depositor is attempting to withdraw\n */\n function withdrawDeposit(uint256[] memory _depositIds) external {\n uint256 returnAmount;\n\n for (uint256 i = 0; i < _depositIds.length; ++i) {\n uint256 depositId = _depositIds[i];\n Deposit storage deposit = deposits[depositId];\n\n require(deposit.depositor == msg.sender, \"Sender must be the depositor\");\n\n (\n bytes32[] memory prunableIntents,\n uint256 reclaimableAmount\n ) = _getPrunableIntents(depositId);\n\n _pruneIntents(deposit, prunableIntents);\n\n returnAmount += deposit.remainingDeposits + reclaimableAmount;\n \n deposit.outstandingIntentAmount -= reclaimableAmount;\n\n emit DepositWithdrawn(depositId, deposit.depositor, deposit.remainingDeposits + reclaimableAmount);\n \n delete deposit.remainingDeposits;\n _closeDepositIfNecessary(depositId, deposit);\n }\n\n usdc.transfer(msg.sender, returnAmount);\n }\n\n /* ============ Governance Functions ============ */\n\n /**\n * @notice GOVERNANCE ONLY: Updates the send processor address used for validating and interpreting zk proofs.\n *\n * @param _sendProcessor New send proccesor address\n */\n function setSendProcessor(IWiseSendProcessor _sendProcessor) external onlyOwner {\n sendProcessor = _sendProcessor;\n emit NewSendProcessorSet(address(_sendProcessor));\n }\n\n\n /**\n * @notice GOVERNANCE ONLY: Updates the minimum deposit amount a user can specify for off-ramping.\n *\n * @param _minDepositAmount The new minimum deposit amount\n */\n function setMinDepositAmount(uint256 _minDepositAmount) external onlyOwner {\n require(_minDepositAmount != 0, \"Minimum deposit cannot be zero\");\n\n minDepositAmount = _minDepositAmount;\n emit MinDepositAmountSet(_minDepositAmount);\n }\n\n /**\n * @notice GOVERNANCE ONLY: Updates the sustainability fee. This fee is charged to on-rampers upon a successful on-ramp.\n *\n * @param _fee The new sustainability fee in precise units (10**18, ie 10% = 1e17)\n */\n function setSustainabilityFee(uint256 _fee) external onlyOwner {\n require(_fee <= MAX_SUSTAINABILITY_FEE, \"Fee cannot be greater than max fee\");\n\n sustainabilityFee = _fee;\n emit SustainabilityFeeUpdated(_fee);\n }\n\n /**\n * @notice GOVERNANCE ONLY: Updates the recepient of sustainability fees.\n *\n * @param _feeRecipient The new fee recipient address\n */\n function setSustainabilityFeeRecipient(address _feeRecipient) external onlyOwner {\n require(_feeRecipient != address(0), \"Fee recipient cannot be zero address\");\n\n sustainabilityFeeRecipient = _feeRecipient;\n emit SustainabilityFeeRecipientUpdated(_feeRecipient);\n }\n\n /**\n * @notice GOVERNANCE ONLY: Updates the max amount allowed to be on-ramped in each transaction. To on-ramp more than\n * this amount a user must make multiple transactions.\n *\n * @param _maxOnRampAmount The new max on ramp amount\n */\n function setMaxOnRampAmount(uint256 _maxOnRampAmount) external onlyOwner {\n require(_maxOnRampAmount != 0, \"Max on ramp amount cannot be zero\");\n\n maxOnRampAmount = _maxOnRampAmount;\n emit MaxOnRampAmountSet(_maxOnRampAmount);\n }\n\n /**\n * @notice GOVERNANCE ONLY: Updates the on-ramp cooldown period, once an on-ramp transaction is completed the user must wait this\n * amount of time before they can signalIntent to on-ramp again.\n *\n * @param _onRampCooldownPeriod New on-ramp cooldown period\n */\n function setOnRampCooldownPeriod(uint256 _onRampCooldownPeriod) external onlyOwner {\n onRampCooldownPeriod = _onRampCooldownPeriod;\n emit OnRampCooldownPeriodSet(_onRampCooldownPeriod);\n }\n\n /**\n * @notice GOVERNANCE ONLY: Updates the intent expiration period, after this period elapses an intent can be pruned to prevent\n * locking up a depositor's funds.\n *\n * @param _intentExpirationPeriod New intent expiration period\n */\n function setIntentExpirationPeriod(uint256 _intentExpirationPeriod) external onlyOwner {\n require(_intentExpirationPeriod != 0, \"Max intent expiration period cannot be zero\");\n\n intentExpirationPeriod = _intentExpirationPeriod;\n emit IntentExpirationPeriodSet(_intentExpirationPeriod);\n }\n\n\n /* ============ External View Functions ============ */\n\n function getDeposit(uint256 _depositId) external view returns (Deposit memory) {\n return deposits[_depositId];\n }\n\n function getIdCurrentIntentHash(address _account) public view returns (bytes32) {\n return globalAccount[accountRegistry.getAccountId(_account)].currentIntentHash;\n }\n\n function getIdCurrentIntentHashAsUint(address _account) external view returns (uint256) {\n return uint256(getIdCurrentIntentHash(_account));\n }\n\n function getLastOnRampTimestamp(address _account) external view returns (uint256) {\n return globalAccount[accountRegistry.getAccountId(_account)].lastOnrampTimestamp;\n }\n\n function getIntentsWithOnRamperId(bytes32[] calldata _intentHashes) external view returns (IntentWithOnRamperId[] memory) {\n IntentWithOnRamperId[] memory intentsWithOnRamperId = new IntentWithOnRamperId[](_intentHashes.length);\n\n for (uint256 i = 0; i < _intentHashes.length; ++i) {\n bytes32 intentHash = _intentHashes[i];\n Intent memory intent = intents[intentHash];\n intentsWithOnRamperId[i] = IntentWithOnRamperId({\n intentHash: _intentHashes[i],\n intent: intent,\n onRamperId: accountRegistry.getAccountId(intent.onRamper)\n });\n }\n\n return intentsWithOnRamperId;\n }\n\n function getAccountDeposits(address _account) external view returns (DepositWithAvailableLiquidity[] memory accountDeposits) {\n uint256[] memory accountDepositIds = globalAccount[accountRegistry.getAccountId(_account)].deposits;\n accountDeposits = new DepositWithAvailableLiquidity[](accountDepositIds.length);\n \n for (uint256 i = 0; i < accountDepositIds.length; ++i) {\n uint256 depositId = accountDepositIds[i];\n Deposit memory deposit = deposits[depositId];\n ( , uint256 reclaimableAmount) = _getPrunableIntents(depositId);\n\n accountDeposits[i] = DepositWithAvailableLiquidity({\n depositId: depositId,\n depositorId: accountRegistry.getAccountId(deposit.depositor),\n deposit: deposit,\n availableLiquidity: deposit.remainingDeposits + reclaimableAmount\n });\n }\n }\n\n function getDepositFromIds(uint256[] memory _depositIds) external view returns (DepositWithAvailableLiquidity[] memory depositArray) {\n depositArray = new DepositWithAvailableLiquidity[](_depositIds.length);\n\n for (uint256 i = 0; i < _depositIds.length; ++i) {\n uint256 depositId = _depositIds[i];\n Deposit memory deposit = deposits[depositId];\n ( , uint256 reclaimableAmount) = _getPrunableIntents(depositId);\n\n depositArray[i] = DepositWithAvailableLiquidity({\n depositId: depositId,\n depositorId: accountRegistry.getAccountId(deposit.depositor),\n deposit: deposit,\n availableLiquidity: deposit.remainingDeposits + reclaimableAmount\n });\n }\n\n return depositArray;\n }\n\n /* ============ Internal Functions ============ */\n\n /**\n * @notice Calculates the intentHash of new intent\n */\n function _calculateIntentHash(\n bytes32 _accountId,\n uint256 _depositId\n )\n internal\n view\n virtual\n returns (bytes32 intentHash)\n {\n // Mod with circom prime field to make sure it fits in a 254-bit field\n uint256 intermediateHash = uint256(keccak256(abi.encodePacked(_accountId, _depositId, block.timestamp)));\n intentHash = bytes32(intermediateHash % CIRCOM_PRIME_FIELD);\n }\n\n /**\n * @notice Cycles through all intents currently open on a deposit and sees if any have expired. If they have expired\n * the outstanding amounts are summed and returned alongside the intentHashes\n */\n function _getPrunableIntents(\n uint256 _depositId\n )\n internal\n view\n returns(bytes32[] memory prunableIntents, uint256 reclaimedAmount)\n {\n bytes32[] memory intentHashes = deposits[_depositId].intentHashes;\n prunableIntents = new bytes32[](intentHashes.length);\n\n for (uint256 i = 0; i < intentHashes.length; ++i) {\n Intent memory intent = intents[intentHashes[i]];\n if (intent.intentTimestamp + intentExpirationPeriod < block.timestamp) {\n prunableIntents[i] = intentHashes[i];\n reclaimedAmount += intent.amount;\n }\n }\n }\n\n function _pruneIntents(Deposit storage _deposit, bytes32[] memory _intents) internal {\n for (uint256 i = 0; i < _intents.length; ++i) {\n if (_intents[i] != bytes32(0)) {\n _pruneIntent(_deposit, _intents[i]);\n }\n }\n }\n\n /**\n * @notice Pruning an intent involves deleting its state from the intents mapping, zeroing out the intendee's currentIntentHash in\n * their global account mapping, and deleting the intentHash from the deposit's intentHashes array.\n */\n function _pruneIntent(Deposit storage _deposit, bytes32 _intentHash) internal {\n Intent memory intent = intents[_intentHash];\n\n delete globalAccount[accountRegistry.getAccountId(intent.onRamper)].currentIntentHash;\n delete intents[_intentHash];\n _deposit.intentHashes.removeStorage(_intentHash);\n\n emit IntentPruned(_intentHash, intent.deposit);\n }\n\n /**\n * @notice Removes a deposit if no outstanding intents AND no remaining deposits. Deleting a deposit deletes it from the\n * deposits mapping and removes tracking it in the user's accounts mapping.\n */\n function _closeDepositIfNecessary(uint256 _depositId, Deposit storage _deposit) internal {\n uint256 openDepositAmount = _deposit.outstandingIntentAmount + _deposit.remainingDeposits;\n if (openDepositAmount == 0) {\n globalAccount[accountRegistry.getAccountId(_deposit.depositor)].deposits.removeStorage(_depositId);\n emit DepositClosed(_depositId, _deposit.depositor);\n delete deposits[_depositId];\n }\n }\n\n /**\n * @notice Checks if sustainability fee has been defined, if so sends fee to the fee recipient and intent amount minus fee\n * to the on-ramper. If sustainability fee is undefined then full intent amount is transferred to on-ramper.\n */\n function _transferFunds(bytes32 _intentHash, Intent memory _intent) internal {\n uint256 fee;\n if (sustainabilityFee != 0) {\n fee = (_intent.amount * sustainabilityFee) / PRECISE_UNIT;\n usdc.transfer(sustainabilityFeeRecipient, fee);\n }\n\n uint256 onRampAmount = _intent.amount - fee;\n usdc.transfer(_intent.to, onRampAmount);\n\n emit IntentFulfilled(_intentHash, _intent.deposit, _intent.onRamper, _intent.to, onRampAmount, fee);\n }\n\n /**\n * @notice Validate send payment email and check that it hasn't already been used (done on SendProcessor).\n * Additionally, we validate that the offRamperId matches the one from the specified intent and that enough\n * was paid off-chain inclusive of the conversionRate.\n */\n function _verifyOnRampProof(\n IWiseSendProcessor.SendData calldata _data,\n bytes calldata _verifierSignature\n )\n internal\n returns(Intent storage intent, Deposit storage deposit, bytes32 intentHash)\n {\n intentHash = bytes32(_data.intentHash);\n intent = intents[intentHash];\n require(intent.onRamper == msg.sender, \"Caller must be the on-ramper\");\n\n deposit = deposits[intent.deposit];\n\n (\n uint256 amount,\n uint256 timestamp,\n bytes32 offRamperId,\n bytes32 currencyId\n ) = sendProcessor.processProof(\n IWiseSendProcessor.SendProof({\n public_values: _data,\n proof: _verifierSignature\n }),\n deposit.verifierSigningKey\n );\n\n require(currencyId == deposit.receiveCurrencyId, \"Wrong currency sent\");\n require(intent.intentTimestamp <= timestamp, \"Intent was not created before send\");\n require(accountRegistry.getAccountInfo(deposit.depositor).offRampId == offRamperId, \"Offramper id does not match\");\n require(amount >= (intent.amount * PRECISE_UNIT) / deposit.conversionRate, \"Payment was not enough\");\n }\n}\n" + }, + "contracts/ramps/wise/WiseSendProcessor.sol": { + "content": "//SPDX-License-Identifier: MIT\n\nimport { ECDSA } from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport { SignatureChecker } from \"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\";\n\nimport { IKeyHashAdapterV2 } from \"../../processors/keyHashAdapters/IKeyHashAdapterV2.sol\";\nimport { INullifierRegistry } from \"../../processors/nullifierRegistries/INullifierRegistry.sol\";\nimport { IWiseSendProcessor } from \"./interfaces/IWiseSendProcessor.sol\";\nimport { StringConversionUtils } from \"../../lib/StringConversionUtils.sol\";\nimport { TLSBaseProcessor } from \"../../processors/TLSBaseProcessor.sol\";\n\npragma solidity ^0.8.18;\n\ncontract WiseSendProcessor is IWiseSendProcessor, TLSBaseProcessor {\n\n using ECDSA for bytes32;\n using SignatureChecker for address;\n using StringConversionUtils for string;\n\n /* ============ Constants ============ */\n bytes32 public constant PAYMENT_STATUS = keccak256(abi.encodePacked(\"OUTGOING_PAYMENT_SENT\"));\n\n /* ============ Constructor ============ */\n constructor(\n address _ramp,\n INullifierRegistry _nullifierRegistry,\n uint256 _timestampBuffer,\n string memory _endpoint,\n string memory _host\n )\n TLSBaseProcessor(\n _ramp,\n _nullifierRegistry,\n _timestampBuffer,\n _endpoint,\n _host\n )\n {}\n \n /* ============ External Functions ============ */\n function processProof(\n IWiseSendProcessor.SendProof calldata _proof,\n address _verifierSigningKey\n )\n public\n override\n onlyRamp\n returns(\n uint256 amount,\n uint256 timestamp,\n bytes32 offRamperId,\n bytes32 currencyId\n )\n {\n _validateProof(_verifierSigningKey, _proof.public_values, _proof.proof);\n\n _validateTLSEndpoint(\n endpoint.replaceString(\"*\", _proof.public_values.senderId),\n _proof.public_values.endpoint\n );\n _validateTLSHost(host, _proof.public_values.host);\n \n // Validate status\n require(\n keccak256(abi.encodePacked(_proof.public_values.status)) == PAYMENT_STATUS,\n \"Payment status not confirmed as sent\"\n );\n _validateAndAddNullifier(keccak256(abi.encodePacked(\"Wise\", _proof.public_values.transferId)));\n\n amount = _proof.public_values.amount.stringToUint(6);\n\n // Add the buffer to build in flexibility with L2 timestamps\n timestamp = _proof.public_values.timestamp.stringToUint(0) / 1000 + timestampBuffer;\n\n offRamperId = bytes32(_proof.public_values.recipientId.stringToUint(0));\n currencyId = keccak256(abi.encodePacked(_proof.public_values.currencyId));\n }\n\n /* ============ View Functions ============ */\n\n function verifyProof(\n address _verifierSigningKey,\n IWiseSendProcessor.SendData memory _publicValues, \n bytes memory _proof\n )\n internal\n view\n returns(bool)\n { \n bytes memory encodedMessage = abi.encode(\n _publicValues.endpoint,\n _publicValues.host,\n _publicValues.transferId,\n _publicValues.senderId,\n _publicValues.recipientId,\n _publicValues.amount,\n _publicValues.currencyId,\n _publicValues.status,\n _publicValues.timestamp,\n _publicValues.intentHash\n );\n return _isValidVerifierSignature(encodedMessage, _proof, _verifierSigningKey);\n }\n\n /* ============ Internal Functions ============ */\n\n function _validateProof(\n address _verifierSigningKey,\n IWiseSendProcessor.SendData memory _publicValues, \n bytes memory _proof\n )\n internal\n view\n { \n require(\n verifyProof(_verifierSigningKey, _publicValues, _proof),\n \"Invalid signature from verifier\"\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